<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://dashakid.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://dashakid.github.io/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-10-01T19:03:25+00:00</updated><id>https://dashakid.github.io/feed.xml</id><title type="html">Gian-Carlo Javier</title><subtitle>Gian-Carlo Javier builds ML pipelines, trading systems and AI automations. Build logs on how each system works, what it checks and what broke.</subtitle><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><entry><title type="html">Missed-Call Rescue: texting back before they call someone else</title><link href="https://dashakid.github.io/projects/missed-call-rescue" rel="alternate" type="text/html" title="Missed-Call Rescue: texting back before they call someone else" /><published>2026-08-24T19:00:00+00:00</published><updated>2026-08-24T19:00:00+00:00</updated><id>https://dashakid.github.io/projects/missed-call-rescue</id><content type="html" xml:base="https://dashakid.github.io/projects/missed-call-rescue"><![CDATA[<p>A Twilio-powered SaaS for solo-operator service businesses. When a call goes unanswered it texts the caller back within seconds, follows up until the job is booked, then automates the Google review request afterward. Sold on a setup fee plus monthly retainer.</p>

<h2 id="call-workflow">Call workflow</h2>

<ol>
  <li><strong>Inbound call, no answer:</strong> missed, busy or after-hours.</li>
  <li><strong>Twilio status webhook:</strong> fires on call completion with the disposition.</li>
  <li><strong>Caller lookup:</strong> CRM match, prior history, spam filter.</li>
  <li><strong>Agent drafts the SMS:</strong> context-aware, in the business’s voice, under 10 seconds from the missed call.</li>
  <li><strong>Follow-up sequence:</strong> polite cadence until booked or opted out.</li>
  <li><strong>Google review request:</strong> sent automatically after the job closes, so reviews compound.</li>
</ol>

<h2 id="twilio-endpoints">Twilio endpoints</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Endpoint</th>
      <th style="text-align: left">Job</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">POST /voice</code></td>
      <td style="text-align: left">TwiML answer flow: ring, voicemail fallback, whisper.</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">POST /status</code></td>
      <td style="text-align: left">Status callback → disposition classifier → rescue trigger.</td>
    </tr>
    <tr>
      <td style="text-align: left"><code class="language-plaintext highlighter-rouge">POST /sms</code></td>
      <td style="text-align: left">Two-way thread. Replies route back through the agent.</td>
    </tr>
  </tbody>
</table>

<h2 id="prompt-structure">Prompt structure</h2>

<p>The system prompt gives the agent the business, the caller’s number, the call disposition and any CRM history, and asks for one SMS: warm, specific, under 240 characters, with one clear next step. It is told never to invent availability.</p>

<p>An example thread, with a made-up business:</p>

<blockquote>
  <p><strong>Agent → caller:</strong> Hi! You just called Meridian Dental. Sorry we missed you. Want me to grab you a cleaning slot this week? Reply with a day that works and I’ll lock it in.</p>

  <p><strong>Caller:</strong> thursday afternoon?</p>

  <p><strong>Agent → caller:</strong> Thursday 2:40pm is open with Dr. Reyes. Should I book it under this number?</p>
</blockquote>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[A Twilio SaaS for solo-operator service businesses. An unanswered call gets a text back within seconds, a follow-up until the job is booked, and a Google review request once it's done.]]></summary></entry><entry><title type="html">Cold email agent: outreach that stops when someone replies</title><link href="https://dashakid.github.io/projects/cold-email-agent" rel="alternate" type="text/html" title="Cold email agent: outreach that stops when someone replies" /><published>2026-08-24T18:00:00+00:00</published><updated>2026-08-24T18:00:00+00:00</updated><id>https://dashakid.github.io/projects/cold-email-agent</id><content type="html" xml:base="https://dashakid.github.io/projects/cold-email-agent"><![CDATA[<p>An autonomous outreach agent running on EC2 that handles prospecting and email sequencing end to end: sourcing leads, personalizing openers, sending on a warmed schedule, and watching the inbox for replies.</p>

<h2 id="agent-loop">Agent loop</h2>

<ol>
  <li><strong>Prospect sourcing:</strong> list building and enrichment filters.</li>
  <li><strong>Personalization:</strong> opener drafted per lead from site and profile context.</li>
  <li><strong>Sequencer:</strong> warmed schedule, throttled sends, timezone-aware.</li>
  <li><strong>Inbox watcher:</strong> reply detection pauses the sequence instantly.</li>
  <li><strong>Handoff:</strong> interested replies surfaced for a human to close.</li>
</ol>

<h2 id="design-notes">Design notes</h2>

<ul>
  <li><strong>Autonomous:</strong> runs unattended on EC2. Sourcing, sending and monitoring without a babysitter.</li>
  <li><strong>Deliverability:</strong> warmup ramps and send throttles protect the domain before volume ever scales.</li>
  <li><strong>Stateful:</strong> every lead tracked through the funnel. No double-sends, no dropped threads.</li>
</ul>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[An autonomous agent on EC2 that sources leads, writes a personal opener for each one, sends on a warmed schedule and watches the inbox. A reply pauses the sequence and goes to a human.]]></summary></entry><entry><title type="html">Nine client websites, no framework unless the job needs one</title><link href="https://dashakid.github.io/projects/client-websites" rel="alternate" type="text/html" title="Nine client websites, no framework unless the job needs one" /><published>2026-08-24T17:00:00+00:00</published><updated>2026-08-24T17:00:00+00:00</updated><id>https://dashakid.github.io/projects/client-websites</id><content type="html" xml:base="https://dashakid.github.io/projects/client-websites"><![CDATA[<p>Nine live websites designed, built, and deployed end to end for clients. Performance-first builds with no framework overhead unless the job calls for it. Pintona’s no-build stack started here.</p>

<p>What’s included: design, build, hosting setup and on-page SEO.</p>

<p>Want one? <a href="/#contact">Get in touch</a>.</p>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[Designed, built and deployed end to end. Performance first, plain HTML, CSS and JS by default. Pintona's stack started here.]]></summary></entry><entry><title type="html">In build: Co-Orchestrator</title><link href="https://dashakid.github.io/projects/co-orchestrator" rel="alternate" type="text/html" title="In build: Co-Orchestrator" /><published>2026-08-24T15:00:00+00:00</published><updated>2026-08-24T15:00:00+00:00</updated><id>https://dashakid.github.io/projects/co-orchestrator</id><content type="html" xml:base="https://dashakid.github.io/projects/co-orchestrator"><![CDATA[<p>A multi-agent LLM system that coordinates the OpenAI and Anthropic APIs on the same task: routing subtasks to whichever model does that job best, then merging results into one execution thread.</p>

<p>Notes on the build will go here as it ships.</p>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[A multi-agent system that puts OpenAI and Anthropic models on the same task, routes each subtask to the model that does it best, then merges the results into one execution thread.]]></summary></entry><entry><title type="html">In build: a white-label automation platform</title><link href="https://dashakid.github.io/projects/white-label-platform" rel="alternate" type="text/html" title="In build: a white-label automation platform" /><published>2026-08-24T14:00:00+00:00</published><updated>2026-08-24T14:00:00+00:00</updated><id>https://dashakid.github.io/projects/white-label-platform</id><content type="html" xml:base="https://dashakid.github.io/projects/white-label-platform"><![CDATA[<p>A client-management and marketing automation platform built to be resold under other brands: one codebase, many storefronts.</p>

<p>It grew out of running <a href="/projects/missed-call-rescue">Missed-Call Rescue</a> for real clients. Notes on the build will go here as it ships.</p>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[Client management and marketing automation built to be resold under other brands: one codebase, many storefronts. It grew out of running Missed-Call Rescue for real clients.]]></summary></entry><entry><title type="html">Pintona: a wardrobe app with no build step</title><link href="https://dashakid.github.io/projects/pintona" rel="alternate" type="text/html" title="Pintona: a wardrobe app with no build step" /><published>2026-07-15T00:00:00+00:00</published><updated>2026-07-15T00:00:00+00:00</updated><id>https://dashakid.github.io/projects/pintona</id><content type="html" xml:base="https://dashakid.github.io/projects/pintona"><![CDATA[<p>A mobile-first, no-build Progressive Web App: snap your clothes, build outfits, get an honest AI style opinion.</p>

<blockquote>
  <p><strong>Status:</strong> Deployed, live product at <a href="https://pintona.vercel.app">pintona.vercel.app</a>.
<strong>Core mission:</strong> Digital wardrobe + AI styling, shipped as a real installable app, not a demo.</p>
</blockquote>

<h2 id="architecture">Architecture</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Browser (vanilla JS, ES modules, no build step)
├─ Firebase Auth ────────► Google sign-in
├─ Firestore ─────────────► wardrobe items, outfits, board, style profile
├─ Firebase Storage ──────► garment / reference photos
├─ fetch('/api/gemini') ──► Vercel serverless ──► Gemini 2.5 Flash (AI look feedback)
└─ fetch('/api/removebg') ► Vercel serverless ──► background removal
</code></pre></div></div>

<p>Both serverless routes verify a Firebase ID token before doing any work. No unauthenticated calls to either API.</p>

<h2 id="key-features">Key features</h2>

<ul>
  <li><strong>AI styling feedback:</strong> Gemini 2.5 Flash rates outfits against a chosen “vibe” and the user’s own style-reference photos.</li>
  <li><strong>Wardrobe management:</strong> photo upload, client-side compression, auto-categorization, background removal.</li>
  <li><strong>Today tab:</strong> AI picks an outfit of the day using the wardrobe, inspiration board, active vibe, and local weather (Open-Meteo, keyless).</li>
  <li><strong>i18n:</strong> full English / Spanish / Vietnamese translation, switchable in-app.</li>
  <li><strong>PWA:</strong> installable, offline-aware service worker, works as a real home-screen app on iOS and Android via “Add to Home Screen.”</li>
</ul>

<h2 id="performance">Performance</h2>

<table>
  <thead>
    <tr>
      <th>Lighthouse</th>
      <th>Score</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Performance</td>
      <td>97</td>
    </tr>
    <tr>
      <td>Accessibility</td>
      <td>100</td>
    </tr>
    <tr>
      <td>Best practices</td>
      <td>96</td>
    </tr>
    <tr>
      <td>Time to interactive</td>
      <td>~1.2s</td>
    </tr>
  </tbody>
</table>

<h2 id="tech-stack">Tech stack</h2>

<ul>
  <li><strong>Frontend:</strong> Vanilla JS, ES modules, no bundler. Zero build step by design.</li>
  <li><strong>Auth/Data:</strong> Firebase Auth, Firestore, Storage.</li>
  <li><strong>AI:</strong> Gemini 2.5 Flash (styling feedback), background removal pipeline.</li>
  <li><strong>Infra:</strong> Vercel serverless functions (<code class="language-plaintext highlighter-rouge">/api/gemini</code>, <code class="language-plaintext highlighter-rouge">/api/removebg</code>), CSP/security headers.</li>
  <li><strong>PWA:</strong> Service worker (network-first HTML/JS, stale-while-revalidate for images/fonts), install manifest.</li>
</ul>

<h2 id="why-no-build-step">Why no build step</h2>

<p>A deliberate choice: zero tooling means zero drift between what’s on disk and what runs. Any file can be opened and understood top to bottom without reverse-engineering a bundle, and deploys are just “copy the files.” Bundling/TypeScript would be a deliberate future migration, not incremental drift.</p>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[Snap your clothes, build outfits, get an honest score from Gemini. A vanilla-JS PWA on Firebase in English, Spanish and Vietnamese, installable on iOS and Android.]]></summary></entry><entry><title type="html">ReviewSignal: reading reviews in two languages</title><link href="https://dashakid.github.io/projects/reviewsignal" rel="alternate" type="text/html" title="ReviewSignal: reading reviews in two languages" /><published>2026-07-15T00:00:00+00:00</published><updated>2026-07-15T00:00:00+00:00</updated><id>https://dashakid.github.io/projects/reviewsignal</id><content type="html" xml:base="https://dashakid.github.io/projects/reviewsignal"><![CDATA[<p>A dual-notebook system that turns raw customer reviews into decision-ready intelligence reports, in English and Spanish.</p>

<blockquote>
  <p><strong>How it’s sold:</strong> fixed scope, fixed price, 5–7 day delivery, delivered as a shareable HTML report. A productized service, not an open-ended engagement.
<strong>Core mission:</strong> Turn bulk product/service reviews into sentiment breakdowns, recurring complaint/praise themes, and concrete recommendations, without a human reading every review by hand.</p>
</blockquote>

<h2 id="pipeline-overview">Pipeline overview</h2>

<p>Both language versions follow the same 7-step pipeline:</p>

<ol>
  <li><strong>Load &amp; normalize:</strong> ingest reviews (Amazon, Shopify, Trustpilot, MercadoLibre, a Kaggle dataset or a custom CSV), map columns to a platform-agnostic schema.</li>
  <li><strong>Sentiment labeling:</strong> star ratings as ground truth; sentiment model scores as a continuous signal.</li>
  <li><strong>Sentiment by product:</strong> surfaces which products/SKUs carry the most negativity.</li>
  <li><strong>Sentiment over time:</strong> tracks whether sentiment is trending up, down, or spiking.</li>
  <li><strong>Topic modeling:</strong> NMF extracts the top recurring complaint and praise themes.</li>
  <li><strong>Recommendations:</strong> quantifies each complaint theme and ties it to affected SKUs. Themes are ranked by frequency × sentiment severity, not raw counts.</li>
  <li><strong>Export:</strong> Markdown summary + supporting CSVs + a standalone HTML report.</li>
</ol>

<h2 id="english-vs-spanish">English vs. Spanish</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Aspect</th>
      <th style="text-align: left">English</th>
      <th style="text-align: left">Spanish</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><strong>Sentiment model</strong></td>
      <td style="text-align: left">VADER (lexicon-based)</td>
      <td style="text-align: left">nlptown/bert-base-multilingual-uncased-sentiment (neural)</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Why</strong></td>
      <td style="text-align: left">Fast, no model download</td>
      <td style="text-align: left">Native Spanish grammar/accent handling, context-aware</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Stop words</strong></td>
      <td style="text-align: left">English-optimized</td>
      <td style="text-align: left">Spanish-optimized</td>
    </tr>
  </tbody>
</table>

<h2 id="logic-highlight-topic-extraction">Logic highlight: topic extraction</h2>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">vectorizer</span> <span class="o">=</span> <span class="n">TfidfVectorizer</span><span class="p">(</span><span class="n">stop_words</span><span class="o">=</span><span class="n">STOP_WORDS</span><span class="p">,</span> <span class="n">ngram_range</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="n">max_df</span><span class="o">=</span><span class="mf">0.95</span><span class="p">)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">vectorizer</span><span class="p">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">review_texts</span><span class="p">)</span>

<span class="n">nmf</span> <span class="o">=</span> <span class="n">NMF</span><span class="p">(</span><span class="n">n_components</span><span class="o">=</span><span class="n">N_TOPICS</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="mi">42</span><span class="p">,</span> <span class="n">max_iter</span><span class="o">=</span><span class="mi">500</span><span class="p">)</span>
<span class="n">W</span> <span class="o">=</span> <span class="n">nmf</span><span class="p">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
<span class="n">H</span> <span class="o">=</span> <span class="n">nmf</span><span class="p">.</span><span class="n">components_</span>

<span class="k">for</span> <span class="n">topic_idx</span><span class="p">,</span> <span class="n">topic</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">H</span><span class="p">):</span>
    <span class="n">top_words</span> <span class="o">=</span> <span class="p">[</span><span class="n">feature_names</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">topic</span><span class="p">.</span><span class="n">argsort</span><span class="p">()[</span><span class="o">-</span><span class="mi">8</span><span class="p">:][::</span><span class="o">-</span><span class="mi">1</span><span class="p">]]</span>
    <span class="c1"># -&gt; recurring theme, ranked by share of negative/positive reviews
</span></code></pre></div></div>

<h2 id="outputs">Outputs</h2>

<ul>
  <li><code class="language-plaintext highlighter-rouge">reviewsignal_report.md</code>: sentiment mix, top 5 complaint themes, top 5 praised features, ranked recommendations</li>
  <li><code class="language-plaintext highlighter-rouge">reviewsignal_report.html</code>: standalone report with embedded charts</li>
  <li><code class="language-plaintext highlighter-rouge">top_complaints.csv</code> / <code class="language-plaintext highlighter-rouge">top_praise.csv</code> / <code class="language-plaintext highlighter-rouge">recommendations.csv</code>: structured tables per theme</li>
</ul>

<h2 id="tech-stack">Tech stack</h2>

<ul>
  <li><strong>NLP:</strong> VADER, Hugging Face Transformers (multilingual BERT), scikit-learn (TF-IDF, NMF)</li>
  <li><strong>Data:</strong> Pandas, NumPy, kagglehub for dataset ingestion</li>
  <li><strong>Reporting:</strong> Matplotlib, Seaborn, Jupyter/nbformat</li>
</ul>

<h2 id="real-world-note">Real-world note</h2>

<p>Topic modeling needs volume to find genuine recurring patterns. The pipeline is built for bulk datasets (hundreds to tens of thousands of reviews), the scale a DTC/e-commerce brand generates on Amazon, Shopify, or Trustpilot. For a business with a handful of reviews, reading them directly beats statistical topic modeling. The tool is built for the scale where that stops being true.</p>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[Reviews from Amazon, Shopify, Trustpilot or MercadoLibre become one report: sentiment, the top recurring complaints and praise, and 3 to 5 quantified recommendations. Fixed scope, fixed price.]]></summary></entry><entry><title type="html">Kakashi postmortem: the strategy worked, the exchange didn’t</title><link href="https://dashakid.github.io/projects/polymarket" rel="alternate" type="text/html" title="Kakashi postmortem: the strategy worked, the exchange didn’t" /><published>2026-05-13T00:00:00+00:00</published><updated>2026-05-13T00:00:00+00:00</updated><id>https://dashakid.github.io/projects/polymarket</id><content type="html" xml:base="https://dashakid.github.io/projects/polymarket"><![CDATA[<p>A Polymarket copy-trading bot deployed to EC2. It tracks top wallets and mirrors high-conviction positions through a risk-gate stack.</p>

<h2 id="copy-trade-flow">Copy-trade flow</h2>

<ol>
  <li><strong>Top-wallet tracker:</strong> Polymarket leaderboard and position ingest.</li>
  <li><strong>Conviction filter:</strong> signal only when a bet is at least 10% of that wallet’s 7-day volume.</li>
  <li><strong>Risk gate stack:</strong> confidence thresholds, exposure caps.</li>
  <li><strong>CLOB execution:</strong> order placement against Polymarket’s book.</li>
</ol>

<h2 id="postmortem">Postmortem</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: left"> </th>
      <th style="text-align: left"> </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><strong>Validated</strong></td>
      <td style="text-align: left">Paper trading confirmed the copy-strategy edge end to end on EC2.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Blocked</strong></td>
      <td style="text-align: left">An exchange-side CLOB order version mismatch rejected live orders. A bug on their end, not the strategy’s.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Status</strong></td>
      <td style="text-align: left">Infrastructure intact and redeployable. Live trading waits on the exchange fix.</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="from-the-original-write-up-may-2026">From the original write-up (May 2026)</h2>

<!-- This section is the May 2026 write-up, kept as published apart from its "live since April" status line. Trim it if parts no longer apply. -->

<p>A multi-signal prediction market system with wallet intelligence and risk-gated CLOB execution. The core mission: identify mispriced prediction markets and execute with confidence-weighted position sizing and hard risk controls.</p>

<h3 id="the-signal-pipeline">The signal pipeline</h3>

<ol>
  <li><strong>Market inputs:</strong> ingests Kraken OHLCV, Polymarket order books, top-wallet on-chain activity, and macro/event context in real time via WebSocket.</li>
  <li><strong>Feature layer:</strong> engineers signals: Bollinger Bands, RSI, momentum, token normalization, wallet conviction ranking, volatility, and edge calculations.</li>
  <li><strong>Decision layer:</strong> routes signals across concurrent strategies (directional, market-making, wallet-following, arbitrage, event forecasting).</li>
  <li><strong>Risk gate stack:</strong> validates confidence threshold, edge minimum, exposure cap, and position guards before any order is approved.</li>
  <li><strong>Executor (CLOB):</strong> creates, routes, and posts orders with stateful retries and fill handling.</li>
  <li><strong>Operator feedback:</strong> Discord alerts, process monitor, trade logs, win/loss dashboards, and analytics state via PostgreSQL.</li>
</ol>

<h3 id="risk-gate-stack">Risk gate stack</h3>

<p>Every order passes through a multi-layer gate before execution. If any layer fails, the order is blocked and logged. The system never silently skips a check.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Layer</th>
      <th style="text-align: left">Component</th>
      <th style="text-align: left">Function</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><strong>Layer 1</strong></td>
      <td style="text-align: left"><strong>Confidence threshold</strong></td>
      <td style="text-align: left">Blocks any signal below 60% model confidence.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Layer 2</strong></td>
      <td style="text-align: left"><strong>Edge minimum</strong></td>
      <td style="text-align: left">Requires at least 3% edge over market implied probability.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Layer 3</strong></td>
      <td style="text-align: left"><strong>Exposure cap</strong></td>
      <td style="text-align: left">Hard cap on total portfolio exposure. No exceptions.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Layer 4</strong></td>
      <td style="text-align: left"><strong>Deduplication guard</strong></td>
      <td style="text-align: left">Prevents double-entry on the same market across strategies.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Layer 5</strong></td>
      <td style="text-align: left"><strong>Inventory guard</strong></td>
      <td style="text-align: left">Tracks open positions and blocks conflicting directional exposure.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Layer 6</strong></td>
      <td style="text-align: left"><strong>Timeout exit</strong></td>
      <td style="text-align: left">Forces position closure if hold time exceeds configured maximum.</td>
    </tr>
  </tbody>
</table>

<h3 id="logic-highlight-confidence-weighted-sizing">Logic highlight: confidence-weighted sizing</h3>

<p>Position size scales with signal confidence and edge. High-conviction signals get larger allocation; weak signals get minimum size or are blocked entirely.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">calculate_position_size</span><span class="p">(</span><span class="n">confidence</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">edge</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">portfolio</span><span class="p">:</span> <span class="nb">dict</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span><span class="p">:</span>
    <span class="s">"""
    Scales position size based on signal quality.
    Never exceeds portfolio exposure cap regardless of confidence.
    """</span>
    <span class="n">base_size</span> <span class="o">=</span> <span class="n">portfolio</span><span class="p">[</span><span class="s">"base_position_size"</span><span class="p">]</span>
    <span class="n">max_size</span> <span class="o">=</span> <span class="n">portfolio</span><span class="p">[</span><span class="s">"max_position_size"</span><span class="p">]</span>

    <span class="n">quality_multiplier</span> <span class="o">=</span> <span class="p">(</span><span class="n">confidence</span> <span class="o">-</span> <span class="mf">0.60</span><span class="p">)</span> <span class="o">*</span> <span class="n">edge</span> <span class="o">*</span> <span class="mi">10</span>
    <span class="n">raw_size</span> <span class="o">=</span> <span class="n">base_size</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">quality_multiplier</span><span class="p">)</span>

    <span class="k">return</span> <span class="nb">min</span><span class="p">(</span><span class="n">raw_size</span><span class="p">,</span> <span class="n">max_size</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="tech-stack">Tech stack</h3>

<ul>
  <li><strong>Execution:</strong> Polymarket CLOB API, Kraken WebSocket API.</li>
  <li><strong>Orchestration:</strong> Python asyncio, multi-strategy concurrent runners.</li>
  <li><strong>State management:</strong> Redis (real-time order book, deduplication), PostgreSQL (trade logs, analytics).</li>
  <li><strong>Risk controls:</strong> custom risk gate engine with 6 validation layers.</li>
  <li><strong>Infrastructure:</strong> Docker, environment-based config, unless-stopped restart policy.</li>
  <li><strong>Observability:</strong> Discord webhooks (live alerts), structured logging, win/loss dashboards.</li>
</ul>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[A Polymarket copy-trader on EC2 that mirrors high-conviction positions from top wallets. Paper trading validated it. Then an exchange-side CLOB order version mismatch rejected every live order.]]></summary></entry><entry><title type="html">CoKeeper: teaching a classifier to say “I’m not sure”</title><link href="https://dashakid.github.io/projects/cokeeper" rel="alternate" type="text/html" title="CoKeeper: teaching a classifier to say “I’m not sure”" /><published>2026-04-03T00:00:00+00:00</published><updated>2026-04-03T00:00:00+00:00</updated><id>https://dashakid.github.io/projects/cokeeper</id><content type="html" xml:base="https://dashakid.github.io/projects/cokeeper"><![CDATA[<p>Automating General Ledger classification for accountants using specialized ML pipelines.</p>

<blockquote>
  <p><strong>Impact:</strong> Reduces manual categorization time by ~16×, turning 8 hours of manual entry into 30 minutes of high-level review. 92.5% accuracy in production.</p>
</blockquote>

<h2 id="the-problem">The problem</h2>

<p>Accountants spend significant billable hours manually sorting hundreds of bank transactions. The patterns are repetitive, but the data is “dirty”: merchant strings are inconsistent, containing transaction IDs, locations, and cryptic abbreviations that standard rule-based systems fail to catch.</p>

<h2 id="the-solution-confidence-tiered-automation">The solution: confidence-tiered automation</h2>

<p>CoKeeper doesn’t just categorize; it assesses its own certainty. By outputting predictions in three confidence tiers, it creates a clear, trustworthy workflow for the user.</p>

<table>
  <thead>
    <tr>
      <th>Tier</th>
      <th>Confidence</th>
      <th>Accuracy</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Green</strong></td>
      <td>≥ 80%</td>
      <td><strong>99.2%</strong></td>
      <td>Auto-import, no review needed</td>
    </tr>
    <tr>
      <td><strong>Yellow</strong></td>
      <td>50–80%</td>
      <td><strong>94.8%</strong></td>
      <td>Quick spot-check</td>
    </tr>
    <tr>
      <td><strong>Red</strong></td>
      <td>&lt; 50%</td>
      <td><strong>56.3%</strong></td>
      <td>Manual review required</td>
    </tr>
  </tbody>
</table>

<p><strong>Success metric:</strong> ~59% of all transactions land in the <strong>green</strong> tier, ready for instant import.</p>

<h2 id="pipeline">Pipeline</h2>

<ol>
  <li><strong>Bank CSV ingest:</strong> raw exports, any institution’s format.</li>
  <li><strong>Merchant string cleaner:</strong> strips transaction IDs, locations and cryptic abbreviations.</li>
  <li><strong>5-level vendor cascade:</strong> exact, alias, fuzzy, pattern, then ML fallback.</li>
  <li><strong>Dual-model classifier:</strong> CatBoost and scikit-learn.</li>
  <li><strong>Confidence tiers → QuickBooks export:</strong> green auto-imports, yellow gets a spot-check, red goes to review.</li>
</ol>

<h2 id="system-architecture">System architecture</h2>

<p>The system is built as a modular, serverless pipeline deployed on <strong>GCP Cloud Run</strong>.</p>

<h3 id="1-vendor-intelligence-5-level-cascade">1. Vendor intelligence (5-level cascade)</h3>

<p>A custom feature engineering system that resolves messy bank descriptions into clean vendor identities:</p>

<ul>
  <li><strong>Level 0:</strong> Normalization (stripping prefixes, locations, and phone numbers).</li>
  <li><strong>Level 1-2:</strong> Exact and fuzzy matching (SequenceMatcher ≥ 0.75).</li>
  <li><strong>Level 3:</strong> Universal merchant database and keyword inference.</li>
</ul>

<h3 id="2-dual-model-routing">2. Dual-model routing</h3>

<p>Instead of a single classifier, CoKeeper routes data through two specialized <strong>CatBoost</strong> models:</p>

<ul>
  <li><strong>Matched vendor model:</strong> used when vendor intelligence recognizes the merchant (92.1% accuracy).</li>
  <li><strong>Unmatched vendor model:</strong> relies on raw text features for unknown merchants (73.7% accuracy).</li>
</ul>

<h2 id="logic-highlight-the-confidence-engine">Logic highlight: the confidence engine</h2>

<p>This snippet shows how the system converts raw model probabilities into actionable business tiers.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">get_confidence_tier</span><span class="p">(</span><span class="n">probabilities</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">float</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
    <span class="s">"""
    Categorizes the prediction based on the model's top-1 certainty.
    Ensures 'Green' tier maintains near-perfect precision for auto-posting.
    """</span>
    <span class="n">top_prob</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">probabilities</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">top_prob</span> <span class="o">&gt;=</span> <span class="mf">0.80</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">{</span><span class="s">"tier"</span><span class="p">:</span> <span class="s">"GREEN"</span><span class="p">,</span> <span class="s">"action"</span><span class="p">:</span> <span class="s">"AUTO_POST"</span><span class="p">,</span> <span class="s">"color"</span><span class="p">:</span> <span class="s">"#22c55e"</span><span class="p">}</span>
    <span class="k">elif</span> <span class="n">top_prob</span> <span class="o">&gt;=</span> <span class="mf">0.50</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">{</span><span class="s">"tier"</span><span class="p">:</span> <span class="s">"YELLOW"</span><span class="p">,</span> <span class="s">"action"</span><span class="p">:</span> <span class="s">"SPOT_CHECK"</span><span class="p">,</span> <span class="s">"color"</span><span class="p">:</span> <span class="s">"#eab308"</span><span class="p">}</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="p">{</span><span class="s">"tier"</span><span class="p">:</span> <span class="s">"RED"</span><span class="p">,</span> <span class="s">"action"</span><span class="p">:</span> <span class="s">"MANUAL_REVIEW"</span><span class="p">,</span> <span class="s">"color"</span><span class="p">:</span> <span class="s">"#ef4444"</span><span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[Accountants spend billable hours sorting bank transactions with dirty merchant strings. CoKeeper runs each one through a five-level vendor cascade and a dual-model classifier, then sorts results into green, yellow and red tiers so people only review what needs it.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://dashakid.github.io/assets/cokeeper-ui.jpg" /><media:content medium="image" url="https://dashakid.github.io/assets/cokeeper-ui.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Stock trading bot: momentum rotation with a crash guard</title><link href="https://dashakid.github.io/projects/trading-bot" rel="alternate" type="text/html" title="Stock trading bot: momentum rotation with a crash guard" /><published>2026-04-03T00:00:00+00:00</published><updated>2026-04-03T00:00:00+00:00</updated><id>https://dashakid.github.io/projects/trading-bot</id><content type="html" xml:base="https://dashakid.github.io/projects/trading-bot"><![CDATA[<p>An ML momentum-rotation strategy trading the Nasdaq-100, live on Alpaca paper trading since April 2026.</p>

<h2 id="strategy-flow">Strategy flow</h2>

<ol>
  <li><strong>Alpaca WebSocket:</strong> Nasdaq-100 quotes and daily bars, auto-reconnect with backoff.</li>
  <li><strong>Redis cache + Postgres:</strong> hot tick fan-out, 126 days of price history.</li>
  <li><strong>CatBoost momentum scorer:</strong> ranks the universe on 126-day lookback features.</li>
  <li><strong>Monthly rebalance planner:</strong> target weights, turnover-aware rotation.</li>
  <li><strong>Risk gates → Alpaca paper:</strong> crash guard, sector cap, idempotent orders, full audit trail.</li>
</ol>

<h2 id="risk-rules">Risk rules</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Rule</th>
      <th style="text-align: left">What it does</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><strong>Crash guard</strong></td>
      <td style="text-align: left">Regime filter. When the index breaks trend, the book rotates to cash instead of chasing momentum down.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Sector cap</strong></td>
      <td style="text-align: left">Concentration ceiling so a hot sector can’t own the whole portfolio.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Paper first</strong></td>
      <td style="text-align: left">Live on Alpaca paper since April 2026. The real execution path, zero live capital until the track record earns it.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Monthly cadence</strong></td>
      <td style="text-align: left">Rebalance is scheduled, not reactive. No intraday overtrading.</td>
    </tr>
  </tbody>
</table>

<h2 id="tech-stack">Tech stack</h2>

<p>CatBoost, FastAPI, Redis, PostgreSQL, Alpaca WebSocket.</p>

<hr />

<h2 id="from-the-original-write-up-april-2026">From the original write-up (April 2026)</h2>

<!-- This section is the April 2026 write-up, kept as published. It describes a LangGraph + Claude architecture; trim or delete it if it no longer applies. -->

<blockquote>
  <p><strong>Status at the time:</strong> Phase 10, 14-day paper trading validation.
<strong>Core mission:</strong> Execute high-probability trades with “Defense in Depth” safety protocols.</p>
</blockquote>

<p>The bot operated as a stateful graph where each node is a specialized agent, so market data, sentiment, and risk are analyzed in a strict, logical sequence.</p>

<h3 id="the-langgraph-pipeline">The LangGraph pipeline</h3>

<ol>
  <li><strong>Scanner:</strong> ranks top tickers (AAPL, NVDA, etc.) via Claude based on momentum and volatility.</li>
  <li><strong>Market data:</strong> fetches OHLCV data and computes technical indicators (<strong>RSI, MACD, Bollinger Bands</strong>).</li>
  <li><strong>Research:</strong> aggregates news sentiment and fundamental analysis.</li>
  <li><strong>Strategy:</strong> Claude synthesizes data into a concrete signal (entry, SL, TP).</li>
  <li><strong>Risk gate:</strong> a 6-layer validation check (circuit breaker, position limits, R:R ratio).</li>
  <li><strong>Human gate:</strong> terminal-based approval interrupt for final execution authority.</li>
  <li><strong>Executor:</strong> automated order submission to the <strong>Alpaca API</strong>.</li>
  <li><strong>Journal:</strong> post-trade analysis saved to <strong>PostgreSQL</strong> for continuous learning.</li>
</ol>

<h3 id="defense-in-depth-safety-system">“Defense in depth” safety system</h3>

<p>Capital preservation is more important than profit.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Layer</th>
      <th style="text-align: left">Component</th>
      <th style="text-align: left">Function</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><strong>Layer 1</strong></td>
      <td style="text-align: left"><strong>Redis circuit breaker</strong></td>
      <td style="text-align: left">Hard-stop on all trading if daily loss hits <strong>$150</strong>.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Layer 2</strong></td>
      <td style="text-align: left"><strong>Paper guard</strong></td>
      <td style="text-align: left">Hard-coded block that prevents live execution unless two separate flags are met.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Layer 3</strong></td>
      <td style="text-align: left"><strong>Risk gate</strong></td>
      <td style="text-align: left">Validates risk/reward is <strong>≥ 2.0</strong> and position size is capped at <strong>$500</strong>.</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Layer 4</strong></td>
      <td style="text-align: left"><strong>Human-in-the-loop</strong></td>
      <td style="text-align: left">Requires manual approval in the terminal before any order hits the broker.</td>
    </tr>
  </tbody>
</table>

<h3 id="backtesting">Backtesting</h3>

<p>A dedicated backtesting engine (<code class="language-plaintext highlighter-rouge">scripts/backtest.py</code>) replicates live signal logic without LLM costs: long-only momentum, 3% stop loss / 6% take profit, with Sharpe ratio, profit factor and max drawdown tracked by the journal agent.</p>

<h3 id="graduation-criteria-paper--live">Graduation criteria (paper → live)</h3>

<ol>
  <li>Zero unhandled exceptions over 14 days.</li>
  <li>At least 20 full cycles completed.</li>
  <li>Safety block rate remains below 30%.</li>
  <li>100% adherence to the $500 position limit.</li>
</ol>]]></content><author><name>Gian-Carlo Javier</name><email>dashakid@live.com</email></author><summary type="html"><![CDATA[An ML momentum-rotation strategy on the Nasdaq-100: 126-day lookback, monthly rebalance. CatBoost scores the universe. A crash guard and a sector cap keep the book honest when the regime turns.]]></summary></entry></feed>