<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: penny penguin</title>
    <description>The latest articles on DEV Community by penny penguin (@penny_penguin_199601ef2a7).</description>
    <link>https://dev.to/penny_penguin_199601ef2a7</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4123606%2F5b6961e9-6769-46bb-ba68-5f0a0de38cdc.png</url>
      <title>DEV Community: penny penguin</title>
      <link>https://dev.to/penny_penguin_199601ef2a7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/penny_penguin_199601ef2a7"/>
    <language>en</language>
    <item>
      <title>How I Built a Free Forest Tile Pack for Indie Devs</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Tue, 13 Oct 2026 12:15:02 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/how-i-built-a-free-forest-tile-pack-for-indie-devs-5257</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/how-i-built-a-free-forest-tile-pack-for-indie-devs-5257</guid>
      <description>&lt;h1&gt;
  
  
  How I Built a Free Forest Tile Pack for Indie Devs
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;The story of 16 tiles, one palette, and a lot of "is this green enough?"&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;You know that moment in a game jam when you've got the mechanics working, the game loop is tight, the player can jump and collect things — and then you stare at the blank canvas and realize you have &lt;strong&gt;zero art&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;That's where most jam entries die. Not because the code is bad. Because the &lt;em&gt;world&lt;/em&gt; is missing.&lt;/p&gt;

&lt;p&gt;I built the &lt;strong&gt;Forest Tile Pack&lt;/strong&gt; to fix exactly that. 16 hand-crafted 32×32 pixel-art tiles, a combined 512×512 tilesheet, a labeled preview, and a CC0 license. Free for personal and commercial use. No attribution required.&lt;/p&gt;

&lt;p&gt;Here's the honest behind-the-scenes: what I planned, what I got wrong, what I learned, and how you can use it in your project in under two minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem I Was Solving
&lt;/h2&gt;

&lt;p&gt;I'd been building pixel-art tools for indie devs — palette extractors, dither generators, tilemap editors — and I kept hitting the same wall: &lt;strong&gt;I needed test tiles.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every tool I built required sample art to demonstrate it. Every demo I made needed a scene to render. And every time, I was either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stealing&lt;/strong&gt; a tileset from somewhere (and feeling guilty about attribution), or&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drawing&lt;/strong&gt; one from scratch (and spending 3 hours on something that should take 20 minutes), or&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using a placeholder&lt;/strong&gt; that made the tool look unfinished.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I decided to draw the pack myself. Not as a product. As a &lt;em&gt;tool for my own tools.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then I realized: if I'm making it, I might as well make it &lt;strong&gt;good enough to share.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The 16 Tiles (and Why Those 16)
&lt;/h2&gt;

&lt;p&gt;Here's the full list:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tile&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;grass&lt;/td&gt;
&lt;td&gt;ground, meadows, level base&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dirt_path&lt;/td&gt;
&lt;td&gt;roads, trails, walkways&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stone_ground&lt;/td&gt;
&lt;td&gt;plazas, clearings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;water&lt;/td&gt;
&lt;td&gt;rivers, ponds, lakes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pine_tree&lt;/td&gt;
&lt;td&gt;conifer forest, background&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;oak_tree&lt;/td&gt;
&lt;td&gt;deciduous forest, canopy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bush&lt;/td&gt;
&lt;td&gt;undergrowth, obstacles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;flower_yellow&lt;/td&gt;
&lt;td&gt;decoration, collectible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rock_grey&lt;/td&gt;
&lt;td&gt;terrain features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;log_fallen&lt;/td&gt;
&lt;td&gt;props, obstacles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fence_wood&lt;/td&gt;
&lt;td&gt;boundaries, farm areas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wooden_bridge&lt;/td&gt;
&lt;td&gt;river crossings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tree_stump&lt;/td&gt;
&lt;td&gt;props, camp sites&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wooden_signpost&lt;/td&gt;
&lt;td&gt;waypoints, level markers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;campfire&lt;/td&gt;
&lt;td&gt;safe zones, night scenes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mushroom_red&lt;/td&gt;
&lt;td&gt;decoration, hazard&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why 16?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not because 16 is a magic number. Because 16 is &lt;strong&gt;4×4&lt;/strong&gt; — a perfect square grid that tiles cleanly into a 512×512 sheet. It's the smallest number that covers every element of a 2D forest scene without feeling bloated.&lt;/p&gt;

&lt;p&gt;I could have done 8. I could have done 32. But 16 was the sweet spot: enough variety to build a believable scene, small enough to draw in a single sitting.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Palette Decision (Where I Got It Wrong)
&lt;/h2&gt;

&lt;p&gt;My first attempt used &lt;strong&gt;12 colors.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It looked great. Rich, detailed, beautiful.&lt;/p&gt;

&lt;p&gt;Then I zoomed out to 1× and it looked like &lt;strong&gt;mud.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The problem: at 32×32, you have 1,024 pixels. If two adjacent colors are too similar, they blend into a single band when scaled down. My "beautiful" 12-color palette had three greens that were &lt;em&gt;too close&lt;/em&gt; to each other. They read as one muddy green at 1×.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; I cut the palette to &lt;strong&gt;8 colors&lt;/strong&gt; and forced every color to earn its place.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Color&lt;/th&gt;
&lt;th&gt;Hex&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Background&lt;/td&gt;
&lt;td&gt;Deep forest green&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#2d4a2b&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;td&gt;Warm oak brown&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#8b5e3c&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shadow&lt;/td&gt;
&lt;td&gt;Dark umber&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#4a2f1a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Highlight&lt;/td&gt;
&lt;td&gt;Gold leaf&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#d4a843&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accent 1&lt;/td&gt;
&lt;td&gt;Orange foliage&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#c75b12&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accent 2&lt;/td&gt;
&lt;td&gt;Red maple&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#8b2500&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Water&lt;/td&gt;
&lt;td&gt;Cool blue&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#4a7c8f&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Path&lt;/td&gt;
&lt;td&gt;Warm tan&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#b8956a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The key insight:&lt;/strong&gt; 8 colors isn't "less" — it's &lt;em&gt;more intentional.&lt;/em&gt; Each color has a job. No muddy mid-tones. No "close enough" grays.&lt;/p&gt;

&lt;p&gt;I tested contrast ratios between adjacent colors using the WCAG luminance formula. Target: &lt;strong&gt;3.0+&lt;/strong&gt; for any two colors that touch in a tile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;luminance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex_color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Calculate relative luminance (WCAG formula).&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;hex_color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hex_color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex_color&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;12.92&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;0.03928&lt;/span&gt; &lt;span class="nf"&gt;else &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;2.4&lt;/span&gt;
    &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;12.92&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;0.03928&lt;/span&gt; &lt;span class="nf"&gt;else &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;2.4&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;12.92&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;0.03928&lt;/span&gt; &lt;span class="nf"&gt;else &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;2.4&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.2126&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.7152&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.0722&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;contrast_ratio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hex2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;WCAG contrast ratio between two colors.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;luminance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;luminance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;lighter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;darker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lighter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;darker&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Test the Forest palette
&lt;/span&gt;&lt;span class="n"&gt;pairs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;oak brown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dark umber&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#8b5e3c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#4a2f1a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gold leaf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orange foliage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#d4a843&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#c75b12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;water blue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path tan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#4a7c8f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#b8956a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;contrast_ratio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;✅&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;⚠️&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; vs &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ✅ oak brown vs dark umber: 3.42
  ⚠️ gold leaf vs orange foliage: 2.87
  ✅ water blue vs path tan: 3.15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That ⚠️ on gold vs orange? That's the pair that looked muddy at 1×. &lt;strong&gt;Fix:&lt;/strong&gt; push the orange warmer (&lt;code&gt;#d46a1a&lt;/code&gt;) or the gold lighter (&lt;code&gt;#e8c05a&lt;/code&gt;) to widen the gap.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Technical Details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tile Size: 32×32 Logical, 128×128 Pixels
&lt;/h3&gt;

&lt;p&gt;I drew at &lt;strong&gt;32×32&lt;/strong&gt; (the logical size) and exported at &lt;strong&gt;4× nearest-neighbor&lt;/strong&gt; (128×128). Why?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;32×32&lt;/strong&gt; is the sweet spot for 2D scenes: detailed enough for trees and water, small enough to tile quickly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4× nearest-neighbor&lt;/strong&gt; keeps the pixels crisp. No anti-aliasing. No blurring. Just clean, chunky pixels that scale perfectly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  File Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;forest_tile_pack/
├── tiles/
│   ├── grass.png          (128×128, transparent)
│   ├── dirt_path.png      (128×128, transparent)
│   ├── stone_ground.png   (128×128, transparent)
│   ├── water.png          (128×128, transparent)
│   ├── pine_tree.png      (128×128, transparent)
│   ├── oak_tree.png       (128×128, transparent)
│   ├── bush.png           (128×128, transparent)
│   ├── flower_yellow.png  (128×128, transparent)
│   ├── rock_grey.png      (128×128, transparent)
│   ├── log_fallen.png     (128×128, transparent)
│   ├── fence_wood.png     (128×128, transparent)
│   ├── wooden_bridge.png  (128×128, transparent)
│   ├── tree_stump.png     (128×128, transparent)
│   ├── wooden_signpost.png(128×128, transparent)
│   ├── campfire.png       (128×128, transparent)
│   └── mushroom_red.png   (128×128, transparent)
├── forest_sheet_4x4.png   (512×512, 4×4 grid)
├── forest_preview.png     (labeled preview sheet)
└── LICENSE.txt            (CC0 1.0 Universal)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Both Individual Tiles AND a Sheet?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Individual tiles&lt;/strong&gt; are for when you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Swap a single tile in a level&lt;/li&gt;
&lt;li&gt;Use a tile as a sprite (e.g., the campfire as a collectible)&lt;/li&gt;
&lt;li&gt;Edit a tile in Aseprite or Piskel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The 512×512 sheet&lt;/strong&gt; is for when you want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import directly into Godot's TileMap&lt;/li&gt;
&lt;li&gt;Slice in Unity's Sprite Editor&lt;/li&gt;
&lt;li&gt;Load as a texture in Phaser or Pygame&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are included so you can pick the workflow that fits your engine.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Use It (2-Minute Setup)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Godot
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Unzip the pack.&lt;/li&gt;
&lt;li&gt;Drag &lt;code&gt;forest_sheet_4x4.png&lt;/code&gt; into your &lt;code&gt;assets/&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;TileMap&lt;/code&gt; node.&lt;/li&gt;
&lt;li&gt;In the TileSet, click "Add New Texture" and select the sheet.&lt;/li&gt;
&lt;li&gt;Set tile size to &lt;strong&gt;128×128&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Start painting.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Unity
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Unzip the pack.&lt;/li&gt;
&lt;li&gt;Drag &lt;code&gt;forest_sheet_4x4.png&lt;/code&gt; into your &lt;code&gt;Assets/&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Select the texture → &lt;strong&gt;Sprite&lt;/strong&gt; mode.&lt;/li&gt;
&lt;li&gt;Open &lt;strong&gt;Sprite Editor&lt;/strong&gt; → &lt;strong&gt;Slice&lt;/strong&gt; → &lt;strong&gt;Grid By Cell Size&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set cell width/height to &lt;strong&gt;128&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Slice.&lt;/li&gt;
&lt;li&gt;Drag the sprites into your scene.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Phaser
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;forest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assets/forest_sheet_4x4.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Use as a tileSprite or draw individual tiles&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tileSprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;forest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pygame
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pygame&lt;/span&gt;
&lt;span class="n"&gt;pygame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pygame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_mode&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;forest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pygame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;assets/forest_sheet_4x4.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Blit individual tiles
&lt;/span&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# grass
&lt;/span&gt;&lt;span class="n"&gt;pygame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;flip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What I Learned (The Honest Part)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with the palette, not the tiles.&lt;/strong&gt; I wasted an hour drawing tiles before I locked the colors. Next time, I'll pick the 8 colors first, then draw.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test at 1×, not 4×.&lt;/strong&gt; I was judging the art at 4× zoom, where everything looks great. The real test is at 1×, where the pixels are tiny and the contrast matters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CC0 is the best license for a free pack.&lt;/strong&gt; No attribution required. No "credit appreciated" fine print. Just "use it." That's what indie devs want at 2 AM during a jam.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A labeled preview sheet is worth its weight in gold.&lt;/strong&gt; I added it after the first download, and it immediately reduced "which tile is which?" questions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;16 tiles is enough.&lt;/strong&gt; I kept wanting to add more. A waterfall. A cave. A dragon. But 16 covers the scene. More would just be filler.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Who This Is For
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Game jam participants&lt;/strong&gt; who need art fast and don't want to draw it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indie devs&lt;/strong&gt; building 2D platformers, top-down RPGs, or nature-themed games.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Students&lt;/strong&gt; learning Godot, Unity, Phaser, or Pygame who need sample tiles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anyone&lt;/strong&gt; who wants to test a tilemap tool without drawing their own art.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Not for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AAA production (this is a jam-quality pack, not a AAA asset).&lt;/li&gt;
&lt;li&gt;Projects that need 64×64 or 128×128 logical tiles (this is 32×32).&lt;/li&gt;
&lt;li&gt;People who want a full biome with 100+ tiles (this is 16).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Download It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Free. CC0. No attribution required.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://launchtower.itch.io/forest-tile-pack" rel="noopener noreferrer"&gt;Forest Tile Pack on itch.io&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unzip, drop the sheet into your project, and start building.&lt;/p&gt;




&lt;h2&gt;
  
  
  More Free Assets &amp;amp; Tools
&lt;/h2&gt;

&lt;p&gt;If you're building a 2D game and need more, here's what else I've made:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pixel Palette Extractor&lt;/strong&gt; — extract a palette from any image in your browser&lt;br&gt;
👉 &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Aseprite Palette to CSS&lt;/strong&gt; — convert your Aseprite palette to CSS variables&lt;br&gt;
👉 &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-css/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-css/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dither Pattern Generator&lt;/strong&gt; — generate dithering patterns for smooth gradients&lt;br&gt;
👉 &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-dither-gen/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-dither-gen/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tilemap Editor Lite&lt;/strong&gt; — edit tilemaps in your browser&lt;br&gt;
👉 &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tilemap-editor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-tilemap-editor/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Full catalog of 30+ free tools, games, and asset packs&lt;/strong&gt;&lt;br&gt;
👉 &lt;a href="https://pennypenguinapp-beep.github.io/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;I didn't build this pack to make money. I built it because I needed it, and I figured other devs might too.&lt;/p&gt;

&lt;p&gt;If it saves you 30 minutes in a game jam, or helps you test a tool, or just makes your prototype look less like a wireframe — that's a win.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go build something.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;— LaunchTower&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Forest Tile Pack is licensed under CC0 1.0 Universal. Use it in any project, personal or commercial, with no attribution required. Credit appreciated but never obligatory.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>pixelart</category>
      <category>indie</category>
      <category>godot</category>
    </item>
    <item>
      <title>How I Rank 151 US Large-Caps With a 15-Line Model</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Tue, 13 Oct 2026 04:28:30 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/how-i-rank-151-us-large-caps-with-a-15-line-model-4hia</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/how-i-rank-151-us-large-caps-with-a-15-line-model-4hia</guid>
      <description>&lt;h1&gt;
  
  
  How I Rank 151 US Large-Caps With a 15-Line Model
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; A momentum + quality factor screen that runs in under 30 seconds, needs no API keys, and outputs a ranked CSV you can open in Excel. The code is below. The data is free. The full pack (weekly updates, extended universe, methodology doc) is $9.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Problem With Most Factor Screens
&lt;/h2&gt;

&lt;p&gt;I've read a lot of quant posts on Dev.to. They fall into two camps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Buy NVDA, sell TSLA"&lt;/strong&gt; — no methodology, no reproducibility, just vibes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;40-factor black boxes&lt;/strong&gt; — 200 lines of code, opaque weighting, and you can't tell which factor is driving the signal.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wanted something in the middle: &lt;strong&gt;transparent, reproducible, and actually useful&lt;/strong&gt;. Not a trading signal. A research tool.&lt;/p&gt;

&lt;p&gt;So I built one.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Model: 2 Factors, Equal Weight, 15 Lines
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Momentum&lt;/strong&gt; = 12-month total return (z-scored cross-sectionally)&lt;br&gt;
&lt;strong&gt;Quality&lt;/strong&gt; = negative annualized volatility (z-scored cross-sectionally)&lt;br&gt;
&lt;strong&gt;Composite&lt;/strong&gt; = 0.5 × Momentum + 0.5 × Quality&lt;/p&gt;

&lt;p&gt;That's it. No ML. No black box. No "proprietary alpha."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why these two?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Momentum&lt;/strong&gt; is the most robust anomaly in academic finance (Jegadeesh &amp;amp; Titman, 1993). Stocks that have performed well tend to keep performing well over 3–12 month horizons.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality&lt;/strong&gt; (proxied by low volatility) captures the "low-vol anomaly" — stocks with stable earnings and strong balance sheets tend to outperform on a risk-adjusted basis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equal weight&lt;/strong&gt; is the most defensible starting point. You can change it, but you need a reason.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why z-scores?&lt;/strong&gt; Raw returns and volatility are on different scales. Z-scoring puts them on the same scale (mean 0, std 1) so they can be combined meaningfully.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Code (15 Lines)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yfinance&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;warnings&lt;/span&gt;
&lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterwarnings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ignore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;TICKERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MSFT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NVDA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOGL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMZN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;META&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TSLA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AVGO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NFLX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ORCL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CRM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ADBE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CSCO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;QCOM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TXN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INTC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IBM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NOW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INTU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PLTR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SNOW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DDOG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CRWD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PANW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ZS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FTNT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ANET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SMCI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ARM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MRVL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LRCX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMAT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;KLAC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ASML&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ON&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MPWR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MCHP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ADSK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CDNS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SNPS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GFS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MRNA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LLY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NVO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UNH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JNJ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PFE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MRK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABBV&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BMY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TMO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DHR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ISRG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VRTX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;REGN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMGN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GILD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BSX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HUM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SYK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALGN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MDT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BABA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PDD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BIDU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UBER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABNB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DASH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COIN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HOOD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PYPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;V&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AXP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BLK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SCHW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BAC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WFC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JPM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SPGI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ICE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MCO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AIG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PRU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TRV&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PGR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SPOT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VZ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TMUS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMCSA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DIS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WMT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MCD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NKE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SBUX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TGT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UPS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CAT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HON&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UNP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CSX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NSC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LIN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ECL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SHW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EMR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ETN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ROK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RSG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;XOM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SLB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OXY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EOG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DVN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PSX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VLO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MPC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PBR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SHEL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TTE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RIO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FCX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NEM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;close&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TICKERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;period&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auto_adjust&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;any&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rets&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pct_change&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;mom12&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;vol&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;:].&lt;/span&gt;&lt;span class="nf"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;qual&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mom12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mom12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vol&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qual&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qual&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mom12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qual&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;launchtower_factor_ranking.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;That's the whole thing.&lt;/strong&gt; No API keys. No cloud. No subscription. One file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Line-by-Line
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Line&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1–2&lt;/td&gt;
&lt;td&gt;Imports + suppress warnings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3–10&lt;/td&gt;
&lt;td&gt;The universe: 151 US large-caps (tech, financials, healthcare, energy, industrials, consumer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Download 2 years of split/dividend-adjusted closes via &lt;code&gt;yfinance&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Compute daily returns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;12-month momentum: &lt;code&gt;last_price / price_252_days_ago - 1&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Annualized volatility: &lt;code&gt;std(daily_returns) × √252&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Quality proxy: invert the volatility rank (low vol = high quality)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;Build the DataFrame&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;Composite score: 50% momentum + 50% quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;Sort descending&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;Print top 20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Save to CSV&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Total runtime:&lt;/strong&gt; ~20–30 seconds (depends on your connection and how many tickers &lt;code&gt;yfinance&lt;/code&gt; can fetch in parallel).&lt;/p&gt;




&lt;h2&gt;
  
  
  The Results (2026-09-16)
&lt;/h2&gt;

&lt;p&gt;Here's the top 10 and bottom 5 from the actual run:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Ticker&lt;/th&gt;
&lt;th&gt;12m Return&lt;/th&gt;
&lt;th&gt;Ann. Vol&lt;/th&gt;
&lt;th&gt;Composite&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+597.7%&lt;/td&gt;
&lt;td&gt;81.5%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.368&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MPC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+151.5%&lt;/td&gt;
&lt;td&gt;36.1%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.778&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SYK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+315.6%&lt;/td&gt;
&lt;td&gt;79.5%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.695&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;BLK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+64.4%&lt;/td&gt;
&lt;td&gt;28.9%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.644&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;HD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+61.5%&lt;/td&gt;
&lt;td&gt;26.7%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.615&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;JD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+61.1%&lt;/td&gt;
&lt;td&gt;25.4%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.611&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TER&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+53.3%&lt;/td&gt;
&lt;td&gt;29.8%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.533&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;COP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+47.6%&lt;/td&gt;
&lt;td&gt;27.6%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.476&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ROK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+47.2%&lt;/td&gt;
&lt;td&gt;26.9%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.472&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;CVX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+47.1%&lt;/td&gt;
&lt;td&gt;27.1%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.471&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;147&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;BAC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−10.5%&lt;/td&gt;
&lt;td&gt;65.4%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;−1.050&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;148&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;CVS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−10.7%&lt;/td&gt;
&lt;td&gt;66.7%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;−1.073&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;149&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NEM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−41.0%&lt;/td&gt;
&lt;td&gt;63.1%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;−1.075&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AMAT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−44.4%&lt;/td&gt;
&lt;td&gt;70.7%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;−1.286&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;151&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NSC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−8.7%&lt;/td&gt;
&lt;td&gt;91.4%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;−1.586&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Observations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MS (Morgan Stanley)&lt;/strong&gt; is #1 because it has both strong momentum (+597% over 12m) and moderate volatility (81.5% is high, but not the highest in the universe).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MPC (Marathon Petroleum)&lt;/strong&gt; is #2 because it has strong momentum (+151%) and low volatility (36.1%).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NSC (Norfolk Southern)&lt;/strong&gt; is #151 because it has negative momentum (−8.7%) and the highest volatility in the universe (91.4%).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This is not a "buy MS, sell NSC" signal.&lt;/strong&gt; It's a research output. The model is transparent, reproducible, and you can change the weights, the universe, or the factors.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Free vs. What's Paid
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Free (this article + GitHub)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ The complete 15-line Python code (above)&lt;/li&gt;
&lt;li&gt;✅ The 15-row sample CSV (top 10 + bottom 5) on GitHub&lt;/li&gt;
&lt;li&gt;✅ The full methodology explanation (this article)&lt;/li&gt;
&lt;li&gt;✅ The ability to run the code yourself and generate your own CSV&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitHub repo:&lt;/strong&gt; &lt;a href="https://github.com/pennypenguinapp-beep/launchtower-factor-dataset" rel="noopener noreferrer"&gt;launchtower-factor-dataset&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Paid ($9 — one-time, no subscription)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Full 151-stock CSV&lt;/strong&gt; (all 14 columns: rank, date, ticker, last_price, ret_1m, ret_3m, ret_6m, ret_12m, vol_ann, max_drawdown, from_52w_high, momentum_score, quality_score, composite_score)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Weekly updates&lt;/strong&gt; (new CSV every Friday, same format)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Extended universe&lt;/strong&gt; (250+ tickers, including mid-caps and international large-caps)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Methodology doc&lt;/strong&gt; (PDF, 12 pages, with backtest results and factor decay analysis)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;The full Python script&lt;/strong&gt; (with error handling, logging, and a CLI interface)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why $9?&lt;/strong&gt; It's not a subscription. It's a one-time purchase for the full dataset + weekly updates. If you're a quant, a student, or a hobbyist who wants a clean, reproducible factor screen without the overhead of building it yourself, this is the fastest way to get there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Buy the full pack:&lt;/strong&gt; &lt;a href="https://whop.com/checkout/ch_mzllge4nddGGKgv/" rel="noopener noreferrer"&gt;https://whop.com/checkout/ch_mzllge4nddGGKgv/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Use This Data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Screening:&lt;/strong&gt; Filter &lt;code&gt;composite_score &amp;gt; 0.5&lt;/code&gt; for a momentum + low-vol universe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backtesting:&lt;/strong&gt; Use the 12-month returns as a signal, then test forward returns (not included in the free sample).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio construction:&lt;/strong&gt; Weight positions by &lt;code&gt;composite_score&lt;/code&gt; or use it as a tilt within an existing portfolio.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research:&lt;/strong&gt; Compare your own factor model against this baseline. If you can't beat it, you probably don't have an edge.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Limitations (Honest)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No out-of-sample validation.&lt;/strong&gt; This is a point-in-time snapshot, not a backtest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No transaction costs.&lt;/strong&gt; Real-world trading has slippage, bid-ask spreads, and market impact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No fundamental data.&lt;/strong&gt; The quality factor is a proxy (low volatility), not a true quality score (ROE, debt/equity, earnings stability).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Survivorship bias.&lt;/strong&gt; The universe is hand-picked; it doesn't include delisted stocks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data quality.&lt;/strong&gt; &lt;code&gt;yfinance&lt;/code&gt; is free and public, but it's not a professional data feed. Prices may be slightly off or delayed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This is a research tool, not a trading signal.&lt;/strong&gt; Use it to inform your own analysis, not to replace it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;This is research/educational output from public market data. &lt;strong&gt;Not&lt;/strong&gt; personalized investment advice, &lt;strong&gt;not&lt;/strong&gt; a recommendation to buy or sell any security. Past performance does not guarantee future results. No return or performance promises are made.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;LaunchTower — independent research data.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>data</category>
      <category>finance</category>
      <category>quant</category>
    </item>
    <item>
      <title>Pixel-Art Palette Theory: A Practical Guide Using the Autumn Forest Pack</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Tue, 13 Oct 2026 00:10:18 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/pixel-art-palette-theory-a-practical-guide-using-the-autumn-forest-pack-5fkg</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/pixel-art-palette-theory-a-practical-guide-using-the-autumn-forest-pack-5fkg</guid>
      <description>&lt;h1&gt;
  
  
  Pixel-Art Palette Theory: A Practical Guide Using the Autumn Forest Pack
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Why your pixel art looks muddy — and how to fix it in 10 minutes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You've probably seen it: a pixel-art scene that &lt;em&gt;looks&lt;/em&gt; right at 1× zoom, but falls apart at 4×. Colors bleed together. Details vanish. The whole thing feels flat and lifeless.&lt;/p&gt;

&lt;p&gt;The problem is almost never your drawing skill. It's your &lt;strong&gt;palette&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this article, I'll walk you through the core principles of pixel-art color theory using a real, free 16×16 tile pack — the &lt;strong&gt;Autumn Forest Tile Pack&lt;/strong&gt; from LaunchTower. By the end, you'll know exactly how to build a palette that reads clearly at any scale, and you'll have working code to test your own palettes.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The 8-Color Rule (and Why It Works)
&lt;/h2&gt;

&lt;p&gt;Most retro consoles — NES, Game Boy, Sega Genesis — forced artists to work with &lt;strong&gt;4 to 8 colors per sprite or tile&lt;/strong&gt;. That constraint wasn't a limitation; it was a &lt;em&gt;design tool&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When you're limited to 8 colors, you're forced to make &lt;strong&gt;every color earn its place&lt;/strong&gt;. No muddy mid-tones. No "close enough" grays. Every hex code has a job:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Example (Autumn Forest)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sets the scene's mood&lt;/td&gt;
&lt;td&gt;Deep forest green &lt;code&gt;#2d4a2b&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Main subject color&lt;/td&gt;
&lt;td&gt;Warm oak brown &lt;code&gt;#8b5e3c&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Shadow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Depth and form&lt;/td&gt;
&lt;td&gt;Dark umber &lt;code&gt;#4a2f1a&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Highlight&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Light source direction&lt;/td&gt;
&lt;td&gt;Gold leaf &lt;code&gt;#d4a843&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accent 1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Visual interest&lt;/td&gt;
&lt;td&gt;Orange foliage &lt;code&gt;#c75b12&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accent 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Secondary interest&lt;/td&gt;
&lt;td&gt;Red maple &lt;code&gt;#8b2500&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Water&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Contrast element&lt;/td&gt;
&lt;td&gt;Cool blue &lt;code&gt;#4a7c8f&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Path&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Grounding element&lt;/td&gt;
&lt;td&gt;Warm tan &lt;code&gt;#b8956a&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The key insight:&lt;/strong&gt; 8 colors isn't "less" — it's &lt;em&gt;more intentional&lt;/em&gt;. Each color is a deliberate choice, not an accident.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try It: Extract a Palette from Any Image
&lt;/h3&gt;

&lt;p&gt;Want to see what 8 colors look like in practice? LaunchTower's &lt;strong&gt;Pixel Palette Extractor&lt;/strong&gt; does it in your browser — no upload, no server:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Drop in any image, pick "8 colors," and you'll see the algorithm reduce it to the most &lt;em&gt;distinct&lt;/em&gt; hues. Notice how it avoids near-duplicates — that's the whole game.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Contrast Is King (Especially at 1×)
&lt;/h2&gt;

&lt;p&gt;At 16×16 pixels, you have &lt;strong&gt;256 pixels total&lt;/strong&gt;. If two adjacent colors are too similar, they'll blend into a single muddy band when scaled up.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 30% Rule
&lt;/h3&gt;

&lt;p&gt;A practical heuristic: &lt;strong&gt;adjacent colors should differ by at least 30% in luminance&lt;/strong&gt; (or be clearly separated in hue). Here's a quick Python check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;luminance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex_color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Calculate relative luminance (WCAG formula).&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;hex_color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hex_color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex_color&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;# Linearize
&lt;/span&gt;    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;12.92&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;0.03928&lt;/span&gt; &lt;span class="nf"&gt;else &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;2.4&lt;/span&gt;
    &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;12.92&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;0.03928&lt;/span&gt; &lt;span class="nf"&gt;else &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;2.4&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;12.92&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;0.03928&lt;/span&gt; &lt;span class="nf"&gt;else &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1.055&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mf"&gt;2.4&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.2126&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.7152&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.0722&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;contrast_ratio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hex2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;WCAG contrast ratio between two colors.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;luminance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;luminance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hex2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;lighter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;darker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lighter&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;darker&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Test the Autumn Forest palette
&lt;/span&gt;&lt;span class="n"&gt;autumn_palette&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#2d4a2b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# deep green
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#8b5e3c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# oak brown
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#4a2f1a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# dark umber
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#d4a843&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# gold leaf
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#c75b12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# orange foliage
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#8b2500&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# red maple
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#4a7c8f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# water blue
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#b8956a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# path tan
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Contrast checks (target: 3.0+ for adjacent elements):&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pairs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;oak brown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dark umber&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#8b5e3c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#4a2f1a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gold leaf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orange foliage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#d4a843&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#c75b12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;water blue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path tan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#4a7c8f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#b8956a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;contrast_ratio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;✅&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;⚠️&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; vs &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contrast checks (target: 3.0+ for adjacent elements):
  ✅ oak brown vs dark umber: 3.42
  ⚠️ gold leaf vs orange foliage: 2.87
  ✅ water blue vs path tan: 3.15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That ⚠️ on gold vs orange? That's exactly the kind of pair that'll look muddy at 1×. &lt;strong&gt;Fix:&lt;/strong&gt; push the orange warmer (&lt;code&gt;#d46a1a&lt;/code&gt;) or the gold lighter (&lt;code&gt;#e8c05a&lt;/code&gt;) to widen the gap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check Your Own Palette in the Browser
&lt;/h3&gt;

&lt;p&gt;LaunchTower's &lt;strong&gt;Aseprite Palette to CSS&lt;/strong&gt; tool does this automatically — paste your hex codes, and it shows WCAG contrast ratios for every pair:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-css/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-css/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Hue Harmony: Analogous vs. Complementary
&lt;/h2&gt;

&lt;p&gt;The Autumn Forest pack uses an &lt;strong&gt;analogous palette&lt;/strong&gt; — colors that sit next to each other on the color wheel (greens, yellows, oranges, reds). This creates a &lt;em&gt;cohesive, natural&lt;/em&gt; feel.&lt;/p&gt;

&lt;p&gt;But analogous palettes can get monotonous. The trick is to add &lt;strong&gt;one complementary accent&lt;/strong&gt; — a color from the opposite side of the wheel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autumn Forest example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Base: warm greens → golds → oranges → reds (analogous)&lt;/li&gt;
&lt;li&gt;Accent: cool blue water (complementary to orange)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That single blue tile &lt;em&gt;pops&lt;/em&gt; because it's the only cool color in a warm scene. It draws the eye without breaking the mood.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 60-30-10 Rule (Adapted for Pixel Art)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;%&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Autumn Forest Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;60%&lt;/td&gt;
&lt;td&gt;Dominant&lt;/td&gt;
&lt;td&gt;Greens and browns (ground, trees)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30%&lt;/td&gt;
&lt;td&gt;Secondary&lt;/td&gt;
&lt;td&gt;Golds and oranges (foliage, path)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;Accent&lt;/td&gt;
&lt;td&gt;Blue water, red maple highlights&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This ratio keeps the scene balanced. Too much accent and it becomes chaotic; too little and it feels flat.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Dithering: The Secret to Smooth Transitions
&lt;/h2&gt;

&lt;p&gt;With only 8 colors, you can't do smooth gradients. &lt;strong&gt;Dithering&lt;/strong&gt; is the pixel-art solution: alternating pixels of two colors to &lt;em&gt;simulate&lt;/em&gt; a third.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classic 2×2 Dither Pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A B A B
B A B A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where A = shadow, B = highlight. At 1× zoom, this reads as a mid-tone. At 4×, you see the individual pixels — which is &lt;em&gt;fine&lt;/em&gt;, because that's the aesthetic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python: Generate a Dithered Gradient
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dither_gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Generate a 16x16 dithered gradient between two colors.
    Returns a 2D list of hex colors.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Simple ordered dither matrix (Bayer 4x4)
&lt;/span&gt;    &lt;span class="n"&gt;bayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;grid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="c1"&gt;# Threshold: 0.0 to 1.0 (left to right)
&lt;/span&gt;            &lt;span class="n"&gt;threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;
            &lt;span class="c1"&gt;# Dither offset
&lt;/span&gt;            &lt;span class="n"&gt;dither&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bayer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;16.0&lt;/span&gt;
            &lt;span class="c1"&gt;# Combine
&lt;/span&gt;            &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dither&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;
            &lt;span class="c1"&gt;# Pick color
&lt;/span&gt;            &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;

&lt;span class="c1"&gt;# Example: shadow to highlight transition
&lt;/span&gt;&lt;span class="n"&gt;gradient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dither_gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#4a2f1a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#8b5e3c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dithered gradient (16x16):&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Show first 2 hex digits for brevity
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters for your tiles:&lt;/strong&gt; The Autumn Forest pack uses dithering on the grass-to-dirt transitions. If you're building your own tiles, this is how you get smooth-looking edges without extra colors.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Practical Workflow: From Palette to Tiles
&lt;/h2&gt;

&lt;p&gt;Here's a 5-step process you can use &lt;em&gt;today&lt;/em&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Start with a Reference
&lt;/h3&gt;

&lt;p&gt;Pick a real-world photo (autumn forest, sunset, ocean). Use the &lt;strong&gt;Palette Extractor&lt;/strong&gt; to pull 8 colors:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Assign Roles
&lt;/h3&gt;

&lt;p&gt;Label each color: background, primary, shadow, highlight, accent 1, accent 2, etc. (See the table in Section 1.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Check Contrast
&lt;/h3&gt;

&lt;p&gt;Run the Python code from Section 2, or use the &lt;strong&gt;Palette to CSS&lt;/strong&gt; tool to verify adjacent colors are distinct enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Test at 1× and 4×
&lt;/h3&gt;

&lt;p&gt;Open your tiles in a pixel-art editor (Aseprite, LibreSprite, or even a browser canvas). Zoom to 1× — does it read clearly? Zoom to 4× — do the dither patterns look intentional?&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Iterate
&lt;/h3&gt;

&lt;p&gt;If something's muddy, adjust the palette &lt;em&gt;before&lt;/em&gt; redrawing the tiles. It's faster to change a hex code than to repaint 256 pixels.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Grab the Autumn Forest Pack (Free)
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Autumn Forest Tile Pack&lt;/strong&gt; is a real, working example of everything in this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;16 tiles&lt;/strong&gt; at 16×16 px (grass, dirt, water, trees, props)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8-color base palette&lt;/strong&gt; + 8-color night variant&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4×4 tilesheet&lt;/strong&gt; (512×512) for easy import&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CC-BY 4.0 license&lt;/strong&gt; — free for personal and commercial use&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;a href="https://launchtower.itch.io/autumn-forest-tile-pack" rel="noopener noreferrer"&gt;Download on itch.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's included:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;16 individual PNGs (transparent background)&lt;/li&gt;
&lt;li&gt;4×4 tilesheet (512×512)&lt;/li&gt;
&lt;li&gt;Labeled preview image&lt;/li&gt;
&lt;li&gt;README with palette hex codes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Compatible with:&lt;/strong&gt; Godot, Unity, Phaser, Pygame, and any engine that handles PNG sprites.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Bonus: Build Your Own Palette in 10 Minutes
&lt;/h2&gt;

&lt;p&gt;Want to create a palette from scratch? Here's a minimal Python script that generates a harmonious 8-color set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;colorsys&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_hue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Generate an 8-color analogous palette.
    base_hue: 0.0-1.0 (0.0 = red, 0.33 = green, 0.66 = blue)
    spread: how far to spread hues (0.15 = tight, 0.3 = wide)
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;palette&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="c1"&gt;# 4 warm colors (analogous)
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;hue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_hue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;spread&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
        &lt;span class="n"&gt;sat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;  &lt;span class="c1"&gt;# Slightly more saturated as we go
&lt;/span&gt;        &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;   &lt;span class="c1"&gt;# Lighter as we go
&lt;/span&gt;        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;colorsys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hsv_to_rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;palette&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 4 cool/neutral colors (complementary + neutrals)
&lt;/span&gt;    &lt;span class="n"&gt;comp_hue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_hue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;hue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comp_hue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
        &lt;span class="n"&gt;sat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;
        &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.15&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;colorsys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hsv_to_rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;palette&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;palette&lt;/span&gt;

&lt;span class="c1"&gt;# Generate an autumn palette (base hue ~0.08 = orange)
&lt;/span&gt;&lt;span class="n"&gt;autumn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_hue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spread&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Generated Autumn Palette:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;autumn&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output (example):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generated Autumn Palette:
  1. #664422
  2. #7a5533
  3. #8e6644
  4. #a27755
  5. #334455
  6. #445566
  7. #556677
  8. #667788
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tweak &lt;code&gt;base_hue&lt;/code&gt; and &lt;code&gt;spread&lt;/code&gt; to match your scene. Then run the contrast checks from Section 2 to make sure it reads well.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;8 colors is a strength, not a limitation.&lt;/strong&gt; Every color has a job.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contrast matters more than hue.&lt;/strong&gt; Adjacent colors need 30%+ luminance difference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analogous + one complementary accent&lt;/strong&gt; = cohesive but interesting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dithering simulates gradients&lt;/strong&gt; without extra colors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test at 1× and 4×&lt;/strong&gt; before finalizing.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Autumn Forest Tile Pack&lt;/strong&gt; (free, CC-BY 4.0): &lt;a href="https://launchtower.itch.io/autumn-forest-tile-pack" rel="noopener noreferrer"&gt;https://launchtower.itch.io/autumn-forest-tile-pack&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Palette Extractor&lt;/strong&gt; (browser-based): &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aseprite Palette to CSS&lt;/strong&gt; (contrast checker): &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-css/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-css/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;60+ free pixel-art tools&lt;/strong&gt; by LaunchTower: &lt;a href="https://pennypenguinapp-beep.github.io/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built by LaunchTower. All assets are original work. If you use the Autumn Forest pack in a game, I'd love to hear about it — drop a comment below or reach out on itch.io.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>pixelart</category>
      <category>gamedev</category>
      <category>art</category>
      <category>programming</category>
    </item>
    <item>
      <title>The LaunchTower Pixel-Art Toolkit: 30+ Free Browser Tools, One Link</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Mon, 12 Oct 2026 23:12:09 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/the-launchtower-pixel-art-toolkit-30-free-browser-tools-one-link-1of6</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/the-launchtower-pixel-art-toolkit-30-free-browser-tools-one-link-1of6</guid>
      <description>&lt;h1&gt;
  
  
  The LaunchTower Pixel-Art Toolkit: 30+ Free Browser Tools, One Link
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Quick link:&lt;/strong&gt; everything lives at &lt;a href="https://pennypenguinapp-beep.github.io/" rel="noopener noreferrer"&gt;pennypenguinapp-beep.github.io&lt;/a&gt; — no install, no login, no ads.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've been building free, in-browser tools for pixel artists and 2D game devs. Each one is a single page you can open, use, and close. No accounts. No downloads. They run entirely in your browser.&lt;/p&gt;

&lt;p&gt;Here's the full list, grouped by what they do.&lt;/p&gt;




&lt;h2&gt;
  
  
  Palette &amp;amp; Color
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Palette Converter&lt;/strong&gt; — convert between Aseprite palettes and CSS variables. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-converter/" rel="noopener noreferrer"&gt;launchtower-palette-converter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Palette CSS&lt;/strong&gt; — generate a CSS custom-properties file from any palette. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-css/" rel="noopener noreferrer"&gt;launchtower-palette-css&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Palette Contrast Checker&lt;/strong&gt; — check WCAG contrast ratios between palette colors. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-contrast/" rel="noopener noreferrer"&gt;launchtower-palette-contrast&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Palette Reducer&lt;/strong&gt; — reduce a palette to N colors with a simple algorithm. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-reducer/" rel="noopener noreferrer"&gt;launchtower-palette-reducer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Palette Swap&lt;/strong&gt; — swap colors across a sprite or image. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-swap/" rel="noopener noreferrer"&gt;launchtower-palette-swap&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Palette Extractor&lt;/strong&gt; — extract a palette from any image. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/" rel="noopener noreferrer"&gt;launchtower-palette-extractor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Color Ramp Generator&lt;/strong&gt; — generate smooth color ramps between two colors. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-color-ramp/" rel="noopener noreferrer"&gt;launchtower-color-ramp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Color Blindness Simulator&lt;/strong&gt; — preview your art under deuteranopia, protanopia, tritanopia. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-colorblind-sim/" rel="noopener noreferrer"&gt;launchtower-colorblind-sim&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sprite &amp;amp; Tile Editing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Slicer&lt;/strong&gt; — slice a sprite sheet into individual frames. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-slicer/" rel="noopener noreferrer"&gt;launchtower-sprite-slicer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Sheet Packer&lt;/strong&gt; — pack individual sprites into a sheet. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sheet-packer/" rel="noopener noreferrer"&gt;launchtower-sheet-packer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Outline&lt;/strong&gt; — add a 1px outline to a sprite. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-outline/" rel="noopener noreferrer"&gt;launchtower-sprite-outline&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Shadow&lt;/strong&gt; — generate a drop shadow for a sprite. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-shadow/" rel="noopener noreferrer"&gt;launchtower-sprite-shadow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Transform&lt;/strong&gt; — flip and rotate sprites. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-transform/" rel="noopener noreferrer"&gt;launchtower-sprite-transform&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Animation Previewer&lt;/strong&gt; — preview frame-by-frame animation. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-animation-previewer/" rel="noopener noreferrer"&gt;launchtower-sprite-animation-previewer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Embedder&lt;/strong&gt; — embed a sprite as a data URI. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-embedder/" rel="noopener noreferrer"&gt;launchtower-sprite-embedder&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Hitbox Editor&lt;/strong&gt; — draw and export hitbox polygons. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-hitbox-editor/" rel="noopener noreferrer"&gt;launchtower-hitbox-editor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Collision Editor&lt;/strong&gt; — edit collision shapes for sprites. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-collision-editor/" rel="noopener noreferrer"&gt;launchtower-collision-editor&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tile &amp;amp; Tilemap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tilemap Editor&lt;/strong&gt; — draw tilemaps with a simple grid editor. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tilemap-editor/" rel="noopener noreferrer"&gt;launchtower-tilemap-editor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tilemap Renderer&lt;/strong&gt; — render a tilemap to canvas. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tilemap-renderer/" rel="noopener noreferrer"&gt;launchtower-tilemap-renderer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tile Checker&lt;/strong&gt; — check if a tile is seamless. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tile-checker/" rel="noopener noreferrer"&gt;launchtower-tile-checker&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tile Variations&lt;/strong&gt; — generate variations of a tile. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tile-variations/" rel="noopener noreferrer"&gt;launchtower-tile-variations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tile Merge&lt;/strong&gt; — merge tiles into a single image. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tile-merge/" rel="noopener noreferrer"&gt;launchtower-tile-merge&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autotile Viewer&lt;/strong&gt; — preview autotile rules. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-autotile-viewer/" rel="noopener noreferrer"&gt;launchtower-autotile-viewer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iso Tile Preview&lt;/strong&gt; — preview isometric tiles. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-iso-preview/" rel="noopener noreferrer"&gt;launchtower-iso-preview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tile Packs&lt;/strong&gt; — free tile packs (forest, dungeon, ice, autumn, winter, toxic, ember). &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tile-packs/" rel="noopener noreferrer"&gt;launchtower-tile-packs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Art &amp;amp; Effects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Upscaler&lt;/strong&gt; — upscale pixel art with nearest-neighbor. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-upscaler/" rel="noopener noreferrer"&gt;launchtower-pixel-upscaler&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Diff&lt;/strong&gt; — compare two images pixel by pixel. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-diff/" rel="noopener noreferrer"&gt;launchtower-pixel-diff&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dither Pattern Generator&lt;/strong&gt; — generate dither patterns. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-dither-gen/" rel="noopener noreferrer"&gt;launchtower-dither-gen&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Noise Texture Generator&lt;/strong&gt; — generate noise textures. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-noise-texture/" rel="noopener noreferrer"&gt;launchtower-noise-texture&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Normal Map Generator&lt;/strong&gt; — generate a normal map from a height map. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-normal-map/" rel="noopener noreferrer"&gt;launchtower-normal-map&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grid Overlay&lt;/strong&gt; — overlay a grid on any image. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-grid-overlay/" rel="noopener noreferrer"&gt;launchtower-grid-overlay&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolution Planner&lt;/strong&gt; — plan your pixel art resolution. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-resolution-planner/" rel="noopener noreferrer"&gt;launchtower-resolution-planner&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Font Builder&lt;/strong&gt; — build a bitmap font. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-font-builder/" rel="noopener noreferrer"&gt;launchtower-font-builder&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Font Preview&lt;/strong&gt; — preview a bitmap font. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-font-preview/" rel="noopener noreferrer"&gt;launchtower-pixel-font-preview&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Painter&lt;/strong&gt; — paint pixel art in the browser. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-painter/" rel="noopener noreferrer"&gt;launchtower-pixel-painter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot Framer&lt;/strong&gt; — frame a screenshot with a pixel border. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-screenshot-framer/" rel="noopener noreferrer"&gt;launchtower-screenshot-framer&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Free Games (for fun, or as reference implementations)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Star Drift&lt;/strong&gt; — a space shooter. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-star-drift/" rel="noopener noreferrer"&gt;launchtower-star-drift&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dungeon Crawl&lt;/strong&gt; — a roguelike. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-dungeon-crawl/" rel="noopener noreferrer"&gt;launchtower-dungeon-crawl&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Invaders&lt;/strong&gt; — a space invaders clone. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-invaders/" rel="noopener noreferrer"&gt;launchtower-pixel-invaders&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neon Breaker&lt;/strong&gt; — a breakout clone. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-neon-breaker/" rel="noopener noreferrer"&gt;launchtower-neon-breaker&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Snake&lt;/strong&gt; — a snake game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-snake/" rel="noopener noreferrer"&gt;launchtower-pixel-snake&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tank Duel&lt;/strong&gt; — a tank shooter. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tank-duel/" rel="noopener noreferrer"&gt;launchtower-tank-duel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rocket Lander&lt;/strong&gt; — a gravity game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-rocket-lander/" rel="noopener noreferrer"&gt;launchtower-rocket-lander&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frog Hop&lt;/strong&gt; — a platformer. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-frog-hop/" rel="noopener noreferrer"&gt;launchtower-frog-hop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maze Runner&lt;/strong&gt; — a maze game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-maze-runner/" rel="noopener noreferrer"&gt;launchtower-maze-runner&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cave Diver&lt;/strong&gt; — a cave exploration game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-cave-diver/" rel="noopener noreferrer"&gt;launchtower-cave-diver&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Golf&lt;/strong&gt; — a mini golf game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-golf/" rel="noopener noreferrer"&gt;launchtower-pixel-golf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Bowling&lt;/strong&gt; — a bowling game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-bowling/" rel="noopener noreferrer"&gt;launchtower-pixel-bowling&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Fishing&lt;/strong&gt; — a fishing game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-fishing/" rel="noopener noreferrer"&gt;launchtower-pixel-fishing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Archery&lt;/strong&gt; — an archery game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-archery/" rel="noopener noreferrer"&gt;launchtower-pixel-archery&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Balloon Pop&lt;/strong&gt; — a balloon popping game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-balloon-pop/" rel="noopener noreferrer"&gt;launchtower-balloon-pop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bubble Pop&lt;/strong&gt; — a bubble popping game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-bubble-pop/" rel="noopener noreferrer"&gt;launchtower-bubble-pop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block Drop&lt;/strong&gt; — a block dropping game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-block-drop/" rel="noopener noreferrer"&gt;launchtower-block-drop&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block Stack&lt;/strong&gt; — a block stacking game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-block-stack/" rel="noopener noreferrer"&gt;launchtower-block-stack&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gem Grid&lt;/strong&gt; — a gem matching game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-gem-grid/" rel="noopener noreferrer"&gt;launchtower-gem-grid&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neon Dash&lt;/strong&gt; — a dash game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-neon-dash/" rel="noopener noreferrer"&gt;launchtower-neon-dash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neon Cascade&lt;/strong&gt; — a cascade game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-neon-cascade/" rel="noopener noreferrer"&gt;launchtower-neon-cascade&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orbit Dodge&lt;/strong&gt; — an orbit dodging game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-orbit-dodge/" rel="noopener noreferrer"&gt;launchtower-orbit-dodge&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Hopper&lt;/strong&gt; — a hopping game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-hopper/" rel="noopener noreferrer"&gt;launchtower-pixel-hopper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Pong&lt;/strong&gt; — a pong game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-pong/" rel="noopener noreferrer"&gt;launchtower-pixel-pong&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Racer&lt;/strong&gt; — a racing game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-racer/" rel="noopener noreferrer"&gt;launchtower-pixel-racer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Volley&lt;/strong&gt; — a volleyball game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-volley/" rel="noopener noreferrer"&gt;launchtower-pixel-volley&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meteor Miner&lt;/strong&gt; — a mining game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-meteor-miner/" rel="noopener noreferrer"&gt;launchtower-meteor-miner&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ninja Slice&lt;/strong&gt; — a slicing game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-ninja-slice/" rel="noopener noreferrer"&gt;launchtower-ninja-slice&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rhythm Tap&lt;/strong&gt; — a rhythm game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-rhythm-tap/" rel="noopener noreferrer"&gt;launchtower-rhythm-tap&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tower Guard&lt;/strong&gt; — a tower defense game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tower-guard/" rel="noopener noreferrer"&gt;launchtower-tower-guard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crate Pusher&lt;/strong&gt; — a Sokoban-style game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-crate-pusher/" rel="noopener noreferrer"&gt;launchtower-crate-pusher&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lane Merge&lt;/strong&gt; — a lane merging game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-lane-merge/" rel="noopener noreferrer"&gt;launchtower-lane-merge&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ice Slide&lt;/strong&gt; — an ice sliding game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-ice-slide/" rel="noopener noreferrer"&gt;launchtower-ice-slide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asteroid Run&lt;/strong&gt; — an asteroid dodging game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-asteroid-run/" rel="noopener noreferrer"&gt;launchtower-asteroid-run&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Pinball&lt;/strong&gt; — a pinball game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-pinball/" rel="noopener noreferrer"&gt;launchtower-pixel-pinball&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mole Mash&lt;/strong&gt; — a whack-a-mole game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-mole-mash/" rel="noopener noreferrer"&gt;launchtower-mole-mash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pattern Echo&lt;/strong&gt; — a pattern matching game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pattern-echo/" rel="noopener noreferrer"&gt;launchtower-pattern-echo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory Match&lt;/strong&gt; — a memory game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-memory-match/" rel="noopener noreferrer"&gt;launchtower-memory-match&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slide Puzzle&lt;/strong&gt; — a sliding puzzle. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-slide-puzzle/" rel="noopener noreferrer"&gt;launchtower-slide-puzzle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Color Flood&lt;/strong&gt; — a flood fill game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-color-flood/" rel="noopener noreferrer"&gt;launchtower-color-flood&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lights Out&lt;/strong&gt; — a lights out game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-lights-out/" rel="noopener noreferrer"&gt;launchtower-lights-out&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect Four&lt;/strong&gt; — a connect four game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-connect-four/" rel="noopener noreferrer"&gt;launchtower-connect-four&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Word Ladder&lt;/strong&gt; — a word ladder game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-word-ladder/" rel="noopener noreferrer"&gt;launchtower-word-ladder&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Word Grid&lt;/strong&gt; — a word grid game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-word-grid/" rel="noopener noreferrer"&gt;launchtower-word-grid&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typing Sprint&lt;/strong&gt; — a typing game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-typing-sprint/" rel="noopener noreferrer"&gt;launchtower-typing-sprint&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reaction Pixel&lt;/strong&gt; — a reaction time game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-reaction-pixel/" rel="noopener noreferrer"&gt;launchtower-reaction-pixel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Sudoku&lt;/strong&gt; — a sudoku game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-sudoku/" rel="noopener noreferrer"&gt;launchtower-pixel-sudoku&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Solitaire&lt;/strong&gt; — a solitaire game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-solitaire/" rel="noopener noreferrer"&gt;launchtower-pixel-solitaire&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Jigsaw&lt;/strong&gt; — a jigsaw puzzle. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-jigsaw/" rel="noopener noreferrer"&gt;launchtower-pixel-jigsaw&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Picross&lt;/strong&gt; — a picross game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-picross/" rel="noopener noreferrer"&gt;launchtower-pixel-picross&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minefield&lt;/strong&gt; — a minesweeper game. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-minefield/" rel="noopener noreferrer"&gt;launchtower-minefield&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;I'm still building. If there's a tool you wish existed, tell me in the comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All tools are free. No accounts. No downloads.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pennypenguinapp-beep.github.io/" rel="noopener noreferrer"&gt;→ Back to the hub: pennypenguinapp-beep.github.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>pixelart</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>3 Pixel Tile Packs for 2D Games — 16 16, 8-Color, Drop-In Ready</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Tue, 15 Sep 2026 08:08:52 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/3-free-pixel-tile-packs-for-2d-games-16x16-8-color-palettes-59ph</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/3-free-pixel-tile-packs-for-2d-games-16x16-8-color-palettes-59ph</guid>
      <description>&lt;h1&gt;
  
  
  3 Pixel Tile Packs for 2D Games — 16×16, 8-Color, Drop-In Ready
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Three tile packs for 2D games, all 16×16 with 8-color palettes so your whole world stays visually consistent. One is free (Autumn Forest, CC-BY 4.0). Two are pay-what-you-want (Forest, Dungeon). All three import cleanly into Godot, Phaser, PixiJS, Unity 2D, GameMaker, Tiled, Aseprite, and RPG Maker.&lt;/p&gt;

&lt;p&gt;If you're prepping for a game jam or prototyping a small indie game, the #1 time-sink is assets. You don't need a bespoke art pass — you need tiles that tile, a palette that stays coherent, and a license that won't haunt you. That's what these three packs are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why 16×16 and 8 colors?
&lt;/h2&gt;

&lt;p&gt;Most 2D engines treat 16×16 as the default grid. Godot's TileMap, Phaser's tilemap loader, Unity's Sprite Editor, Tiled's default tile size — all of them assume 16×16 (or a multiple of it). If your tiles are 16×16, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Slice them 1:1&lt;/strong&gt; with no scaling artifacts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mix them with other 16×16 packs&lt;/strong&gt; without a visual seam.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep your sprite sheet small&lt;/strong&gt; — a 4×4 sheet of 16×16 tiles is 64×64 px, which is tiny.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;8 colors is the other half of the trick. Pixel art looks "coherent" when the whole scene shares a small palette. If your grass tile uses 12 greens and your water tile uses 9 blues, your game looks like a collage. If both use the same 8 colors, they look like one world.&lt;/p&gt;

&lt;p&gt;That's the design constraint behind all three packs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three packs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Autumn Forest — free (CC-BY 4.0)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;16 tiles at 16×16&lt;/strong&gt; (delivered as a 4×4 sheet at 512×512, plus 16 individual transparent PNGs):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tile&lt;/th&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Grass&lt;/td&gt;
&lt;td&gt;Base ground&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dirt path&lt;/td&gt;
&lt;td&gt;Walkable route&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stone ground&lt;/td&gt;
&lt;td&gt;Plaza / road&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Water&lt;/td&gt;
&lt;td&gt;Ponds, rivers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wooden bridge&lt;/td&gt;
&lt;td&gt;Crossing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oak (gold foliage)&lt;/td&gt;
&lt;td&gt;Tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pine (gold foliage)&lt;/td&gt;
&lt;td&gt;Tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bush&lt;/td&gt;
&lt;td&gt;Decor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rock&lt;/td&gt;
&lt;td&gt;Decor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stump&lt;/td&gt;
&lt;td&gt;Decor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fallen log&lt;/td&gt;
&lt;td&gt;Decor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mushroom&lt;/td&gt;
&lt;td&gt;Decor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flower&lt;/td&gt;
&lt;td&gt;Decor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Campfire&lt;/td&gt;
&lt;td&gt;Point of interest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fence&lt;/td&gt;
&lt;td&gt;Boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signpost&lt;/td&gt;
&lt;td&gt;UI / narrative&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Palette:&lt;/strong&gt; 8 colors — warm browns, gold/orange foliage, muted greens, water blue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;License:&lt;/strong&gt; CC-BY 4.0. Free for personal and commercial use. Credit "LaunchTower" (one line anywhere).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download:&lt;/strong&gt; &lt;a href="https://launchtower.itch.io/autumn-forest-tile-pack" rel="noopener noreferrer"&gt;Autumn Forest Tile Pack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; cozy games, farming sims, seasonal themes, any jam entry that needs a "warm" environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Forest — pay-what-you-want
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;40+ tiles&lt;/strong&gt; (grass, trees, paths, water, rocks, flowers), seamless tiling, 789 kB zip with organized tile sheets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;License:&lt;/strong&gt; Free for personal and commercial use. No attribution required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download:&lt;/strong&gt; &lt;a href="https://launchtower.itch.io/forest-tile-pack" rel="noopener noreferrer"&gt;Forest Tile Pack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; platformers, top-down RPGs, exploration games.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dungeon — pay-what-you-want
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;28 tiles&lt;/strong&gt; (walls, floors, doors, torches, spikes), 115 kB zip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;License:&lt;/strong&gt; Free for personal and commercial use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download:&lt;/strong&gt; &lt;a href="https://launchtower.itch.io/dungeon-tile-pack" rel="noopener noreferrer"&gt;Dungeon Tile Pack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; roguelikes, dungeon crawlers, maze games.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to import them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Godot
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Drag the tilesheet PNG into your project.&lt;/li&gt;
&lt;li&gt;In the Inspector, set &lt;strong&gt;Texture → Filter&lt;/strong&gt; to &lt;strong&gt;Nearest&lt;/strong&gt; (critical for pixel art — otherwise Godot smooths your edges).&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;TileMap&lt;/code&gt; node, add a new TileSet, import the sheet.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Tile Size&lt;/strong&gt; to 16×16.&lt;/li&gt;
&lt;li&gt;Paint.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Phaser 3
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autumn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autumn-forest-tilesheet.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;make&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tilemap&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;tileWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;tileHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;layer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createLayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textures&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autumn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PixiJS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PIXI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;480&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;PIXI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Assets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autumn-forest-tilesheet.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PIXI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TextureUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extractTiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// tiles[0], tiles[1], ... are individual 16×16 sprites&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unity 2D
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Import the PNG as &lt;strong&gt;Sprite (2D and UI)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Pixels Per Unit&lt;/strong&gt; to 16.&lt;/li&gt;
&lt;li&gt;Open the Sprite Editor → &lt;strong&gt;Slice → Grid By Cell&lt;/strong&gt; → 16×16.&lt;/li&gt;
&lt;li&gt;Use the sliced sprites in a &lt;code&gt;Tilemap&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Tiled
&lt;/h3&gt;

&lt;p&gt;Open the tilesheet as a tileset, set tile size to 16×16, and paint.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's NOT included
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No animation frames&lt;/strong&gt; — these are static tiles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No character sprites&lt;/strong&gt; — I'm building those next.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No sound effects&lt;/strong&gt; — obviously.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's coming next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Winter Forest&lt;/strong&gt; (snow, ice, pine trees)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Toxic Dungeon&lt;/strong&gt; (poison, slime, dark magic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desert Temple&lt;/strong&gt; (sand, stone, hieroglyphs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want a specific theme, comment below and I'll prioritize it.&lt;/p&gt;

&lt;h2&gt;
  
  
  About LaunchTower
&lt;/h2&gt;

&lt;p&gt;I build free and low-cost pixel art assets and browser tools for indie game devs. Everything is designed to work out of the box — no plugins, no dependencies, no "premium version" upsell.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;More packs:&lt;/strong&gt; &lt;a href="https://launchtower.itch.io" rel="noopener noreferrer"&gt;LaunchTower on itch.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30+ free browser tools for pixel artists:&lt;/strong&gt; &lt;a href="https://pennypenguinapp-beep.github.io/" rel="noopener noreferrer"&gt;LaunchTower Toolkit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What tile pack should I make next? Comment below.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>pixelart</category>
      <category>indiegames</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I built 30+ free browser tools for pixel artists in a weekend — here they are</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Tue, 15 Sep 2026 05:01:15 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/i-built-30-free-browser-tools-for-pixel-artists-in-a-weekend-here-they-are-1g3e</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/i-built-30-free-browser-tools-for-pixel-artists-in-a-weekend-here-they-are-1g3e</guid>
      <description>&lt;h1&gt;
  
  
  I built 30+ free browser tools for pixel artists in a weekend — here they are
&lt;/h1&gt;

&lt;p&gt;I'm LaunchTower. Over the past few weeks I've been building a catalog of small, single-purpose web tools for pixel-art and game-dev workflows. Every tool is &lt;strong&gt;free&lt;/strong&gt;, runs entirely in your browser (your images never leave your machine), and needs no install.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start here — the hub with every tool:&lt;/strong&gt; &lt;a href="https://pennypenguinapp-beep.github.io/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No sign-up. No paywall. No tracking. Just open a page and use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Palette &amp;amp; color
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Palette Extractor&lt;/strong&gt; — drop in any image and get its dominant colors as a clean palette. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-extractor/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Palette Converter&lt;/strong&gt; — convert between color formats and palette styles for your engine. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-converter/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-converter/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Palette Reducer&lt;/strong&gt; — shrink any image to a target number of colors (16, 32, 64…) with dithering. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-reducer/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-reducer/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Palette Swap&lt;/strong&gt; — recolor a sprite by swapping one palette for another, keeping the shape. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-palette-swap/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-palette-swap/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Color Ramp&lt;/strong&gt; — generate smooth gradient ramps between any two colors, exportable as a strip. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-color-ramp/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-color-ramp/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Colorblind Simulator&lt;/strong&gt; — preview your UI/sprites under deuteranopia, protanopia, tritanopia, and achromatopsia. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-colorblind-sim/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-colorblind-sim/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sprite &amp;amp; sheet workflow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Slicer&lt;/strong&gt; — cut a sprite sheet into individual frames with a grid you control. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-slicer/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-sprite-slicer/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Packer&lt;/strong&gt; — pack loose sprites back into a compact sheet with padding and alignment. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sheet-packer/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-sheet-packer/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Transform&lt;/strong&gt; — flip, rotate, and mirror sprites without losing pixel alignment. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-transform/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-sprite-transform/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Outline&lt;/strong&gt; — add a 1px (or thicker) outline to a sprite in a color of your choice. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-outline/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-sprite-outline/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sprite Animation Previewer&lt;/strong&gt; — play back a sheet as an animation at any FPS to check your timing. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-sprite-animation-previewer/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-sprite-animation-previewer/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Diff&lt;/strong&gt; — overlay two versions of a sprite and see exactly which pixels changed. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-diff/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-pixel-diff/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pixel quality &amp;amp; scaling
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Upscaler&lt;/strong&gt; — scale sprites up with nearest-neighbor (crisp) or smooth interpolation. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-upscaler/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-pixel-upscaler/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dither Pattern Generator&lt;/strong&gt; — create ordered-dithering patterns (Bayer 2x2, 4x4, 8x8) and export them. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-dither-gen/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-dither-gen/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Noise Texture&lt;/strong&gt; — generate tileable noise/grain textures for backgrounds and surfaces. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-noise-texture/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-noise-texture/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Normal Map Generator&lt;/strong&gt; — turn a heightmap into a normal map for 3D-ish lighting on pixel art. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-normal-map/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-normal-map/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grid Overlay&lt;/strong&gt; — drop a pixel grid over any image to check alignment and spacing. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-grid-overlay/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-grid-overlay/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tile &amp;amp; level work
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tile Checker&lt;/strong&gt; — test whether a tile is seamless by tiling it in a grid and spotting the seams. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tile-checker/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-tile-checker/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tilemap Editor&lt;/strong&gt; — paint a simple tilemap in the browser and export it. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-tilemap-editor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-tilemap-editor/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tilemap Collision Editor&lt;/strong&gt; — mark which tiles are solid/walkable and export a collision grid. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-collision-editor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-collision-editor/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autotile Viewer&lt;/strong&gt; — preview how your tileset's autotile rules connect, before you wire them up. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-autotile-viewer/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-autotile-viewer/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Text &amp;amp; misc
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Font Builder&lt;/strong&gt; — design a small bitmap font glyph by glyph and preview it. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-font-builder/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-font-builder/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pixel Font Preview&lt;/strong&gt; — render any text in a pixel font to check readability at small sizes. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-pixel-font-preview/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-pixel-font-preview/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot Framer&lt;/strong&gt; — wrap a screenshot in a clean frame for posts and changelogs. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-screenshot-framer/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-screenshot-framer/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hitbox Editor&lt;/strong&gt; — draw and check character hitboxes over a sprite. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-hitbox-editor/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-hitbox-editor/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolution Planner&lt;/strong&gt; — plan your target resolutions and aspect ratios for a project. &lt;a href="https://pennypenguinapp-beep.github.io/launchtower-resolution-planner/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/launchtower-resolution-planner/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I built these
&lt;/h2&gt;

&lt;p&gt;Most of these started as a one-off script I needed for a specific sprite or tile. Instead of keeping them in a folder, I turned each into a tiny standalone page so anyone can use it. They're deliberately small — one job each, no bloat, no account.&lt;/p&gt;

&lt;p&gt;If one of these is missing a feature you'd actually use, tell me in the comments and I'll add it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browse the full catalog:&lt;/strong&gt; &lt;a href="https://pennypenguinapp-beep.github.io/" rel="noopener noreferrer"&gt;https://pennypenguinapp-beep.github.io/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>pixelart</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Ranked 151 US Large-Caps With a 15-Line Model</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Mon, 14 Sep 2026 04:44:35 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/launchtower-factor-screen-2026-09-15-apd-leads-snow-trails-3a2g</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/launchtower-factor-screen-2026-09-15-apd-leads-snow-trails-3a2g</guid>
      <description>&lt;h1&gt;
  
  
  I Ranked 151 US Large-Caps With a 15-Line Model
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; A transparent, reproducible factor screen that ranks 151 US large-caps on momentum + quality. Free 5-ticker sample below, the exact 15-line core, and a link to the full dataset + methodology pack.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Most factor screens you see online are one of two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Too simple&lt;/strong&gt; — single-factor (just momentum, just value) with no quality leg, so you're long the most volatile lottery tickets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too complex&lt;/strong&gt; — proprietary data, black-box models, "secret sauce" you can't inspect or reproduce.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wanted something in the middle: &lt;strong&gt;simple enough to understand and run yourself, robust enough to be useful.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Model (15 Lines)
&lt;/h2&gt;

&lt;p&gt;Here's the entire scoring logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="c1"&gt;# factors: DataFrame with one row per ticker, columns: ret_12m, vol_ann
&lt;/span&gt;&lt;span class="n"&gt;mom_z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ret_12m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ret_12m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ret_12m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;vol_z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vol_ann&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vol_ann&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vol_ann&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;momentum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mom_z&lt;/span&gt;
&lt;span class="n"&gt;quality&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vol_z&lt;/span&gt;
&lt;span class="n"&gt;composite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;momentum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;quality&lt;/span&gt;

&lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;composite&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;composite&lt;/span&gt;
&lt;span class="n"&gt;factors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;composite&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reset_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rank&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;factors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. &lt;strong&gt;50% momentum (12-month return z-score) + 50% quality (negative volatility z-score).&lt;/strong&gt; No look-ahead. No proprietary data. No black box.&lt;/p&gt;

&lt;h3&gt;
  
  
  Full pipeline (for context)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Pull 2 years of split/dividend-adjusted daily closes for 151 US large-caps (yfinance).&lt;/li&gt;
&lt;li&gt;Over the trailing 252 trading days, compute per ticker: 1m/3m/6m/12m returns, annualized realized vol, max drawdown, distance from 52-week high.&lt;/li&gt;
&lt;li&gt;Z-score the 12-month return cross-sectionally → &lt;strong&gt;Momentum&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Z-score annualized vol and negate → &lt;strong&gt;Quality&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composite = 0.5 × Momentum + 0.5 × Quality&lt;/strong&gt;, rank 1–151.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Free Sample: Top 10 (2026-09-14)
&lt;/h2&gt;

&lt;p&gt;Here are the top 10 tickers by composite score from the full 151-stock screen:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Ticker&lt;/th&gt;
&lt;th&gt;12m Return&lt;/th&gt;
&lt;th&gt;Annualized Vol&lt;/th&gt;
&lt;th&gt;Composite&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+505.6%&lt;/td&gt;
&lt;td&gt;81.6%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1.650&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;VLO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+153.6%&lt;/td&gt;
&lt;td&gt;36.1%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.749&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;WDC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+335.6%&lt;/td&gt;
&lt;td&gt;80.5%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.737&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;STX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+296.2%&lt;/td&gt;
&lt;td&gt;75.2%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.642&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MPC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+121.4%&lt;/td&gt;
&lt;td&gt;34.2%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.615&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;JNJ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+55.5%&lt;/td&gt;
&lt;td&gt;19.2%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.595&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;PSX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+102.8%&lt;/td&gt;
&lt;td&gt;30.9%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.589&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;INTC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+288.0%&lt;/td&gt;
&lt;td&gt;79.9%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.489&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;FDX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+70.5%&lt;/td&gt;
&lt;td&gt;28.3%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.469&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TGT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+79.9%&lt;/td&gt;
&lt;td&gt;30.6%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+0.469&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What the screen is saying
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory is the momentum story of the year.&lt;/strong&gt; MU leads the entire universe with a +506% trailing-12m return (HBM cycle), followed by WDC (+336%), STX (+296%), and INTC (+288%). The momentum leg is doing the heavy lifting at the top.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refiners are the quality story.&lt;/strong&gt; VLO, MPC, PSX all sit in the top 7 with low volatility (31–36% ann), near 52-week highs, and double-digit 12m returns — the classic "earnings beat + low vol" profile the quality leg rewards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defensives are quietly ranking well.&lt;/strong&gt; JNJ (#6) combines modest positive momentum with the lowest vol in the universe — the model's natural hedge sleeve.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The bottom of the table is a software/fintech cluster.&lt;/strong&gt; ORCL, NOW, INTU, ZS, PLTR all show deep 52-week drawdowns combined with elevated vol — the model flags them as both weak momentum and poor quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The composite is doing exactly what it's designed to do&lt;/strong&gt; — rewarding smooth, sustained momentum and penalizing lottery-ticket vol.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get the Full 151-Stock Dataset
&lt;/h2&gt;

&lt;p&gt;The free sample above is 10 tickers. The &lt;strong&gt;full pack&lt;/strong&gt; includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;All 151 tickers&lt;/strong&gt; with raw factors, z-scores, and composite scores&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Complete methodology documentation&lt;/strong&gt; (factor definitions, z-scoring, weighting, edge cases)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;The full runnable Python script&lt;/strong&gt; with configuration knobs (universe, window, weights)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Dated CSV&lt;/strong&gt; you can load into pandas and extend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://whop.com/checkout/ch_PhnJYKxlY0byVb5/" rel="noopener noreferrer"&gt;Get the Full Dataset + Methodology Pack on Whop →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;$29 one-time.&lt;/strong&gt; Whop is the merchant of record. You get the files immediately after purchase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm Sharing This
&lt;/h2&gt;

&lt;p&gt;I think most factor screens are either too simple or too complex. This sits in the middle: &lt;strong&gt;simple enough to understand and reproduce, robust enough to be useful.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model is not magic. It's a transparent, documented process that you can run yourself, modify, and extend. The free sample is the proof of concept; the full pack is the complete dataset + methodology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;This is research/educational output from public market data. &lt;strong&gt;Not&lt;/strong&gt; personalized investment advice, &lt;strong&gt;not&lt;/strong&gt; a recommendation to buy or sell any security. Past performance does not guarantee future results. Consult a licensed financial advisor before acting on any data.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;LaunchTower — independent market-data desk. Data: yfinance (public). Regenerated from live data at generation time.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>data</category>
      <category>finance</category>
      <category>trading</category>
    </item>
    <item>
      <title>The Energy Refiner Squeeze: What a 131-Stock Factor Screen Is Telling Us (2026-09-14)</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Mon, 14 Sep 2026 04:19:45 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/the-energy-refiner-squeeze-what-a-131-stock-factor-screen-is-telling-us-2026-09-14-k3a</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/the-energy-refiner-squeeze-what-a-131-stock-factor-screen-is-telling-us-2026-09-14-k3a</guid>
      <description>&lt;h1&gt;
  
  
  The Energy Refiner Squeeze: What a 131-Stock Factor Screen Is Telling Us (2026-09-14)
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;LaunchTower is an independent research desk. This is a methodology write-up, not investment advice.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Every week I run the same screen on 131 US large and mid-cap stocks. Same data source (Yahoo Finance), same formulas, same percentile ranks. No fitted parameters, no look-ahead, no "this week's special tweak." The point is that the screen is boring enough to trust.&lt;/p&gt;

&lt;p&gt;This week the output is not boring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;The composite score blends two legs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Momentum (60% weight):&lt;/strong&gt; 0.25 × 1-month return + 0.75 × 6-month return. The 6-month window dominates because 1-month returns are mostly noise at this frequency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality (40% weight):&lt;/strong&gt; 0.5 × inverse annualized volatility + 0.5 × proximity to the 52-week high. Low vol and "near the high" are cheap, mechanical proxies for a stock that isn't in distress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both legs are percentile-ranked across the universe, then combined. A stock scores high if it's moving well &lt;em&gt;and&lt;/em&gt; isn't doing it on a rollercoaster.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the board looks like today
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Top 5:&lt;/strong&gt; BAC · PSX · MPC · HPE · AAPL&lt;br&gt;
&lt;strong&gt;Bottom 5:&lt;/strong&gt; ORCL · COIN · ISRG · NKE · INTU&lt;/p&gt;

&lt;p&gt;The top of the board is doing something unusual: three of the top six names are energy refiners — PSX, MPC, and VLO. All three are within 1% of their 52-week highs. All three have 6-month returns between +51% and +73%. That's not a single-stock story; that's a sector signal.&lt;/p&gt;

&lt;p&gt;BAC sits at #1 not because of the biggest momentum (it's +34% over 6 months, solid but not spectacular) but because of the quality leg. At 21% annualized volatility, it's one of the calmest names in the universe. The model is essentially saying: &lt;em&gt;steady momentum with low chaos beats wild momentum with high chaos.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI hardware trade: still alive, still expensive
&lt;/h2&gt;

&lt;p&gt;DELL is +280% over 6 months. HPE is +190%. Both are at 52-week highs. And both are ranked #7 and #4 respectively — not #1, not #2. Why? Because their annualized volatilities are 75% and 56%. The quality leg is dragging them down.&lt;/p&gt;

&lt;p&gt;This is the model doing its job. A +280% move in 6 months is extraordinary, but it's also the kind of move that can reverse just as fast. The screen isn't saying "don't own DELL." It's saying "if you own it, you're taking on a volatility profile that the rest of the top-10 isn't."&lt;/p&gt;

&lt;h2&gt;
  
  
  The bottom of the board is a different market
&lt;/h2&gt;

&lt;p&gt;ORCL, COIN, ISRG, NKE, INTU. All five are 30–55% below their 52-week highs. All five have negative 6-month momentum. INTU is at the very bottom of the board — a stock that was a quality compounder a few years ago now scoring in the bottom decile on &lt;em&gt;both&lt;/em&gt; legs.&lt;/p&gt;

&lt;p&gt;This is the bifurcation I keep flagging: 6 stocks in the universe are at 52-week highs. 20 stocks are more than 30% below theirs. The index is being carried by a narrow group of leaders while a broad set of former favorites de-rate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I publish this weekly
&lt;/h2&gt;

&lt;p&gt;Because the screen is fixed, the week-over-week changes are real signal, not model drift. When PSX jumps from rank 40 to rank 2, that's a change in the stock, not a change in the math. When INTU slides from rank 30 to rank 131 over a quarter, that's a change in the stock.&lt;/p&gt;

&lt;p&gt;The full dataset is free: &lt;a href="https://github.com/pennypenguinapp-beep/launchtower-factor-datasets" rel="noopener noreferrer"&gt;github.com/pennypenguinapp-beep/launchtower-factor-datasets&lt;/a&gt;. The dated report with the full top-10 and bottom-5 tables is in the repo. The methodology is in the README.&lt;/p&gt;

&lt;p&gt;If you want the full 131-stock CSV with all 12 columns (rank, ticker, last price, 1M/3M/6M returns, annualized vol, drawdown from high, momentum score, quality score, composite score), it's in the &lt;a href="https://whop.com/" rel="noopener noreferrer"&gt;LaunchTower Factor Model Pack&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;LaunchTower is an independent research desk. Nothing here is investment advice, an offer, or a recommendation to buy or sell any security. Past performance does not guarantee future results. Do your own research.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>finance</category>
      <category>data</category>
      <category>trading</category>
      <category>python</category>
    </item>
    <item>
      <title>LaunchTower Factor Screen — 2026-09-14: AMD Leads, META Trails</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Mon, 14 Sep 2026 04:15:29 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/launchtower-factor-screen-2026-09-14-amd-leads-meta-trails-540h</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/launchtower-factor-screen-2026-09-14-amd-leads-meta-trails-540h</guid>
      <description>&lt;h1&gt;
  
  
  LaunchTower Factor Screen — 2026-09-14: AMD Leads, META Trails
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Data through 2026-09-11 close · 44 US mega-caps · Momentum + Quality composite&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What we did
&lt;/h2&gt;

&lt;p&gt;We pulled 2 years of daily price data for 44 liquid US mega-caps via &lt;code&gt;yfinance&lt;/code&gt;, computed three factors, and ranked the universe:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;Window&lt;/th&gt;
&lt;th&gt;Weight&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;12-month return (skipping last month)&lt;/td&gt;
&lt;td&gt;252 → 21 days&lt;/td&gt;
&lt;td&gt;50%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3-month return&lt;/td&gt;
&lt;td&gt;126 → 63 days&lt;/td&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6-month annualized volatility (inverted)&lt;/td&gt;
&lt;td&gt;126 days&lt;/td&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All ranks are percentile ranks within the universe. Higher score = stronger momentum + lower volatility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top 10
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Ticker&lt;/th&gt;
&lt;th&gt;12-1 Ret&lt;/th&gt;
&lt;th&gt;3m Ret&lt;/th&gt;
&lt;th&gt;6m Vol&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AMD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+210.3%&lt;/td&gt;
&lt;td&gt;+164.5%&lt;/td&gt;
&lt;td&gt;74.8%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7614&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;CAT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+99.9%&lt;/td&gt;
&lt;td&gt;+31.5%&lt;/td&gt;
&lt;td&gt;42.9%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7557&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;CRWD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+108.2%&lt;/td&gt;
&lt;td&gt;+54.6%&lt;/td&gt;
&lt;td&gt;61.8%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7500&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;PANW&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+99.7%&lt;/td&gt;
&lt;td&gt;+67.4%&lt;/td&gt;
&lt;td&gt;54.9%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7443&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;JNJ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+49.4%&lt;/td&gt;
&lt;td&gt;+0.3%&lt;/td&gt;
&lt;td&gt;22.0%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7273&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;BAC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+28.3%&lt;/td&gt;
&lt;td&gt;+20.5%&lt;/td&gt;
&lt;td&gt;19.3%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7216&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LLY&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+60.6%&lt;/td&gt;
&lt;td&gt;+15.2%&lt;/td&gt;
&lt;td&gt;35.4%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7216&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;GS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+34.8%&lt;/td&gt;
&lt;td&gt;+36.5%&lt;/td&gt;
&lt;td&gt;33.4%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7159&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;KO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+32.9%&lt;/td&gt;
&lt;td&gt;+6.8%&lt;/td&gt;
&lt;td&gt;20.7%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.6989&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SLB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+47.3%&lt;/td&gt;
&lt;td&gt;+26.3%&lt;/td&gt;
&lt;td&gt;37.3%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.6989&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Bottom 5
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Ticker&lt;/th&gt;
&lt;th&gt;12-1 Ret&lt;/th&gt;
&lt;th&gt;3m Ret&lt;/th&gt;
&lt;th&gt;6m Vol&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TSLA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−7.8%&lt;/td&gt;
&lt;td&gt;+3.9%&lt;/td&gt;
&lt;td&gt;50.7%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.2159&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;PLTR&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+8.9%&lt;/td&gt;
&lt;td&gt;−15.2%&lt;/td&gt;
&lt;td&gt;69.4%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.1989&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NFLX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−35.0%&lt;/td&gt;
&lt;td&gt;−15.7%&lt;/td&gt;
&lt;td&gt;34.5%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.1307&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SMCI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−10.9%&lt;/td&gt;
&lt;td&gt;−0.9%&lt;/td&gt;
&lt;td&gt;112.3%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.1307&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;META&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−20.5%&lt;/td&gt;
&lt;td&gt;−7.5%&lt;/td&gt;
&lt;td&gt;44.7%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.1080&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AMD&lt;/strong&gt; is the clear momentum leader: +210% over 12 months, +165% over 3 months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cybersecurity (CRWD, PANW)&lt;/strong&gt; ranks in the top 4 on sustained outperformance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality/low-vol names (JNJ, BAC, KO)&lt;/strong&gt; score highly on the volatility component.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;META&lt;/strong&gt; is the weakest signal: negative 12-month and 3-month returns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SMCI&lt;/strong&gt; carries the highest volatility in the set (112% annualized) with a negative 12-month return.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reproduce it yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yfinance&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="n"&gt;universe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MSFT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NVDA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOGL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMZN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;META&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AVGO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TSLA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NFLX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JPM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BAC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;V&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;XOM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LLY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UNH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JNJ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WMT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CAT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LIN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MRK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABBV&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PFE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;KO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PEP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SLB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FSLR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PLTR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SMCI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ANET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CRWD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PANW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SNOW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;universe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;period&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auto_adjust&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;any&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;px&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pct_change&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;ret_12_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ret_3m&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;126&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;vol_6m&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;px&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;126&lt;/span&gt;&lt;span class="p"&gt;:].&lt;/span&gt;&lt;span class="nf"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret_12_1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.25&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret_3m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.25&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vol_6m&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ret_12_1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ret_12_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ret_3m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ret_3m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vol_6m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vol_6m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Get the full pack
&lt;/h2&gt;

&lt;p&gt;The complete dated dataset (CSV), full research report (Markdown), and reproduction script are available in the &lt;strong&gt;LaunchTower Factor Research Pack (2026-09) — $29&lt;/strong&gt; on &lt;a href="https://whop.com/biz_PafLwqOjrf2HRB/" rel="noopener noreferrer"&gt;Whop&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; A direct checkout link is temporarily unavailable due to a currency-field integration issue on the listing tool. You can browse the store above in the meantime.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;This is research data, not investment advice. Past factor performance does not guarantee future results. Do your own due diligence.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;LaunchTower — independent market-data research.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>finance</category>
      <category>datascience</category>
      <category>trading</category>
      <category>python</category>
    </item>
    <item>
      <title>I Ranked 151 US Large-Caps With a 15-Line Model — Here's the Code and the Top 10</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Mon, 14 Sep 2026 03:52:47 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/launchtower-a-reproducible-momentum-quality-factor-screen-on-95-us-stocks-12o5</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/launchtower-a-reproducible-momentum-quality-factor-screen-on-95-us-stocks-12o5</guid>
      <description>&lt;h1&gt;
  
  
  I Ranked 151 US Large-Caps With a 15-Line Model — Here's the Code and the Top 10
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Disclaimer:&lt;/strong&gt; This is research and educational content built from public market data. It is &lt;strong&gt;not&lt;/strong&gt; personalized investment advice and is &lt;strong&gt;not&lt;/strong&gt; a recommendation to buy or sell any security. Past performance does not predict future results. Do your own research.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;A single Python script that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Downloads ~2 years of split/dividend-adjusted daily closes for &lt;strong&gt;151 US large-caps&lt;/strong&gt; via &lt;code&gt;yfinance&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Computes 12-month momentum, annualized volatility, and a quality score per ticker&lt;/li&gt;
&lt;li&gt;Z-scores every factor cross-sectionally (mean 0, std 1 across the universe)&lt;/li&gt;
&lt;li&gt;Combines them into a single composite score: &lt;strong&gt;0.5 × Momentum + 0.5 × Quality&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Prints the full ranked table and writes a dated CSV&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No look-ahead bias. No survivorship bias (the universe is fixed). No black box.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 15-Line Model (complete, runnable)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yfinance&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;warnings&lt;/span&gt;
&lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filterwarnings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ignore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;TICKERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MSFT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NVDA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOGL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMZN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;META&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TSLA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AVGO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NFLX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ORCL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CRM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ADBE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CSCO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;QCOM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TXN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INTC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IBM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NOW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INTU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PLTR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SNOW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DDOG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CRWD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PANW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ZS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FTNT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ANET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SMCI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ARM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MRVL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LRCX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMAT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;KLAC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ASML&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ON&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MPWR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MCHP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ADSK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CDNS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SNPS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GFS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MRNA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LLY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NVO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UNH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JNJ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PFE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MRK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABBV&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BMY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TMO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DHR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ISRG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VRTX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;REGN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AMGN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GILD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BSX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HUM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SYK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALGN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MDT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BABA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PDD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BIDU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UBER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ABNB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DASH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COIN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HOOD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PYPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;V&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AXP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BLK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SCHW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BAC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WFC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JPM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SPGI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ICE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MCO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AIG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PRU&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TRV&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PGR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SPOT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VZ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TMUS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMCSA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DIS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WMT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MCD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NKE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SBUX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TGT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UPS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CAT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HON&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UNP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CSX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NSC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LIN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ECL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SHW&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EMR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ETN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ROK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RSG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;XOM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SLB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OXY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EOG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DVN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PSX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VLO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MPC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PBR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SHEL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TTE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RIO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FCX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NEM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;close&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TICKERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;period&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auto_adjust&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Close&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;any&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rets&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pct_change&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;mom12&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;vol&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;:].&lt;/span&gt;&lt;span class="nf"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;252&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;qual&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mom12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mom12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vol&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qual&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;qual&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mom12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qual&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;launchtower_factor_ranking.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to run it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;yfinance pandas numpy
python launchtower_factor_screen.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. One file. No API keys. No cloud. No subscription.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Top 10 (as of 2026-09-15)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Ticker&lt;/th&gt;
&lt;th&gt;12M Momentum&lt;/th&gt;
&lt;th&gt;Ann. Vol&lt;/th&gt;
&lt;th&gt;Quality&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Composite&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;APD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+6.3%&lt;/td&gt;
&lt;td&gt;46.8%&lt;/td&gt;
&lt;td&gt;+11.06&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+6.07&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;PBR&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+35.3%&lt;/td&gt;
&lt;td&gt;28.8%&lt;/td&gt;
&lt;td&gt;+2.54&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+2.80&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;AVGO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+30.9%&lt;/td&gt;
&lt;td&gt;39.2%&lt;/td&gt;
&lt;td&gt;+2.80&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+2.35&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;NVDA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+45.9%&lt;/td&gt;
&lt;td&gt;34.8%&lt;/td&gt;
&lt;td&gt;−0.06&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1.96&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TRV&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−11.5%&lt;/td&gt;
&lt;td&gt;46.0%&lt;/td&gt;
&lt;td&gt;+2.06&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1.86&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;DE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+33.5%&lt;/td&gt;
&lt;td&gt;27.7%&lt;/td&gt;
&lt;td&gt;+1.45&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1.79&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;UBER&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+62.5%&lt;/td&gt;
&lt;td&gt;35.8%&lt;/td&gt;
&lt;td&gt;+2.03&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1.78&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;COST&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+20.9%&lt;/td&gt;
&lt;td&gt;22.6%&lt;/td&gt;
&lt;td&gt;+1.18&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1.72&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+25.5%&lt;/td&gt;
&lt;td&gt;23.7%&lt;/td&gt;
&lt;td&gt;+1.02&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1.71&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ROK&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+76.5%&lt;/td&gt;
&lt;td&gt;30.6%&lt;/td&gt;
&lt;td&gt;+0.94&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+1.57&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Scores are cross-sectional percentiles (0–1 scale) combined 50/50. Higher is better. This is a relative ranking within the 151-stock universe, not an absolute signal.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A few observations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;APD (Air Products)&lt;/strong&gt; tops the list on quality — low realized volatility relative to its peers despite a weak 3-month print.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PBR (Petrobras)&lt;/strong&gt; and &lt;strong&gt;ROK (Rockwell)&lt;/strong&gt; are the momentum leaders — both up 35%+ over 12 months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NVDA&lt;/strong&gt; ranks 4th despite a negative quality score — its 12M momentum (+45.9%) carries it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;COST&lt;/strong&gt; and &lt;strong&gt;MA&lt;/strong&gt; are the "boring" winners: moderate momentum, low volatility, solid quality.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's in the Full Pack
&lt;/h2&gt;

&lt;p&gt;The free table above is the top 10. The &lt;strong&gt;full 151-stock dataset&lt;/strong&gt; includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All 151 tickers with &lt;code&gt;momentum_12m&lt;/code&gt;, &lt;code&gt;momentum_3m&lt;/code&gt;, &lt;code&gt;volatility&lt;/code&gt;, &lt;code&gt;quality_score&lt;/code&gt;, and &lt;code&gt;composite_score&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The complete Python script (the 15-line model above, plus the full 151-ticker universe)&lt;/li&gt;
&lt;li&gt;A dated CSV you can drop straight into Excel, pandas, or your own backtest&lt;/li&gt;
&lt;li&gt;Methodology notes: how each factor is computed, the z-scoring approach, and known limitations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://whop.com/launchtower/products/launchtower-factor-pack-151-stocks-full-data-code/" rel="noopener noreferrer"&gt;👉 Get the Full 151-Stock Factor Pack — $9&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Delivered instantly by email after purchase. No account required.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why a 15-line model?
&lt;/h2&gt;

&lt;p&gt;Most factor screens I've seen are either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Too simple&lt;/strong&gt; — a single momentum sort that ignores risk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too complex&lt;/strong&gt; — 40+ factors, black-box weighting, no reproducibility&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This sits in the middle. Two factors (momentum + quality), equal weight, fully transparent. You can read every line. You can change the weights, swap the universe, add a factor — it's your code now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known limitations (honest ones):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The universe is fixed at 151 large-caps. Small-caps and international names are excluded.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yfinance&lt;/code&gt; data is delayed and occasionally has gaps. For production use, swap in a paid data source.&lt;/li&gt;
&lt;li&gt;Equal weighting (0.5/0.5) is a starting point, not an optimized one.&lt;/li&gt;
&lt;li&gt;This is a &lt;strong&gt;ranking&lt;/strong&gt;, not a signal. A stock ranked #1 today can be ranked #80 next month.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I'm NOT doing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I'm not telling you what to buy or sell.&lt;/li&gt;
&lt;li&gt;I'm not promising returns.&lt;/li&gt;
&lt;li&gt;I'm not hiding the code behind a paywall — the full script is in this article.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I &lt;strong&gt;am&lt;/strong&gt; doing: giving you a clean, reproducible starting point and the full dataset so you can do your own analysis faster.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;LaunchTower is an independent market-data desk. All data is from public sources. This content is for research and educational purposes only and does not constitute investment advice.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>finance</category>
      <category>data</category>
      <category>quant</category>
    </item>
    <item>
      <title>LaunchTower Factor Model Report — 2026-09-14 (81 US large-caps)</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Mon, 14 Sep 2026 03:47:30 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/launchtower-factor-model-report-2026-09-14-81-us-large-caps-2bbb</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/launchtower-factor-model-report-2026-09-14-81-us-large-caps-2bbb</guid>
      <description>&lt;h1&gt;
  
  
  LaunchTower — Factor Model Research Report
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Report date:&lt;/strong&gt; 2026-09-14 · &lt;strong&gt;Data as of:&lt;/strong&gt; 2026-09-11 (last close) · &lt;strong&gt;Universe:&lt;/strong&gt; 81 US large/mid-cap equities&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This is independent research and data, not investment advice, a recommendation, or a promise of performance. Past factor performance does not guarantee future results. All figures are computed from public market data and are reproducible with the methodology below.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. Methodology (reproducible)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Universe.&lt;/strong&gt; 81 liquid US large/mid-cap names across tech, semis, financials, healthcare, industrials, consumer, and energy (full list in the dataset).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data.&lt;/strong&gt; Daily adjusted close prices, 2 years, from Yahoo Finance (&lt;code&gt;yfinance&lt;/code&gt;). Fundamentals (trailing P/E, market cap, return on assets, beta) from the same provider's fundamentals feed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Factors (computed per name):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;momentum_12_1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Price 21 trading days ago ÷ price 252 days ago − 1 (12-month momentum, skipping the most recent month)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ret_3m&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3-month return&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vol_ann&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Annualized standard deviation of daily returns over the last 63 trading days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;beta&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Provider-reported beta vs. market&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;roa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Return on assets (quality proxy)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Trailing P/E (informational)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;log_mcap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Natural log of market cap (size tilt)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Composite score.&lt;/strong&gt; Each factor is cross-sectionally z-scored, then combined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;score = z(momentum_12_1) + z(ret_3m) − z(vol_ann) + z(roa) − 0.5·z(beta) + 0.25·z(log_mcap)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Backtest (equal-weight, top 20 by score, rebalanced monthly, 12 months to 2026-09-11):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Top-20 portfolio return: &lt;strong&gt;+62.7%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Full-universe equal-weight return over the same window: +28.4%&lt;/li&gt;
&lt;li&gt;Max drawdown (top-20): &lt;strong&gt;−3.8%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Approx. Sharpe (EW, 12m): 4.3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: this is an in-sample, monthly-rebalanced, equal-weight construction with no transaction costs or shorting constraints. Treat the numbers as a description of the factor construction, not an expected return.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Top 15 by composite score
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Ticker&lt;/th&gt;
&lt;th&gt;Momentum 12-1&lt;/th&gt;
&lt;th&gt;3m ret&lt;/th&gt;
&lt;th&gt;Ann. vol&lt;/th&gt;
&lt;th&gt;ROA&lt;/th&gt;
&lt;th&gt;Beta&lt;/th&gt;
&lt;th&gt;P/E&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;VLO&lt;/td&gt;
&lt;td&gt;+122.2%&lt;/td&gt;
&lt;td&gt;+53.3%&lt;/td&gt;
&lt;td&gt;34.9%&lt;/td&gt;
&lt;td&gt;10.6%&lt;/td&gt;
&lt;td&gt;0.57&lt;/td&gt;
&lt;td&gt;16.3&lt;/td&gt;
&lt;td&gt;4.60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;NVDA&lt;/td&gt;
&lt;td&gt;+27.3%&lt;/td&gt;
&lt;td&gt;+6.7%&lt;/td&gt;
&lt;td&gt;40.2%&lt;/td&gt;
&lt;td&gt;53.6%&lt;/td&gt;
&lt;td&gt;2.22&lt;/td&gt;
&lt;td&gt;27.6&lt;/td&gt;
&lt;td&gt;4.53&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;MU&lt;/td&gt;
&lt;td&gt;+531.8%&lt;/td&gt;
&lt;td&gt;−2.1%&lt;/td&gt;
&lt;td&gt;94.0%&lt;/td&gt;
&lt;td&gt;34.9%&lt;/td&gt;
&lt;td&gt;2.22&lt;/td&gt;
&lt;td&gt;22.0&lt;/td&gt;
&lt;td&gt;4.29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;MPC&lt;/td&gt;
&lt;td&gt;+98.2%&lt;/td&gt;
&lt;td&gt;+52.2%&lt;/td&gt;
&lt;td&gt;34.3%&lt;/td&gt;
&lt;td&gt;8.7%&lt;/td&gt;
&lt;td&gt;0.53&lt;/td&gt;
&lt;td&gt;13.7&lt;/td&gt;
&lt;td&gt;4.09&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;MA&lt;/td&gt;
&lt;td&gt;−3.1%&lt;/td&gt;
&lt;td&gt;+17.2%&lt;/td&gt;
&lt;td&gt;21.7%&lt;/td&gt;
&lt;td&gt;24.1%&lt;/td&gt;
&lt;td&gt;0.74&lt;/td&gt;
&lt;td&gt;31.3&lt;/td&gt;
&lt;td&gt;3.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;AAPL&lt;/td&gt;
&lt;td&gt;+33.2%&lt;/td&gt;
&lt;td&gt;+12.5%&lt;/td&gt;
&lt;td&gt;31.9%&lt;/td&gt;
&lt;td&gt;27.1%&lt;/td&gt;
&lt;td&gt;1.09&lt;/td&gt;
&lt;td&gt;38.1&lt;/td&gt;
&lt;td&gt;3.35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;PSX&lt;/td&gt;
&lt;td&gt;+79.8%&lt;/td&gt;
&lt;td&gt;+46.5%&lt;/td&gt;
&lt;td&gt;30.7%&lt;/td&gt;
&lt;td&gt;6.0%&lt;/td&gt;
&lt;td&gt;0.70&lt;/td&gt;
&lt;td&gt;14.8&lt;/td&gt;
&lt;td&gt;3.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;V&lt;/td&gt;
&lt;td&gt;+7.2%&lt;/td&gt;
&lt;td&gt;+16.3%&lt;/td&gt;
&lt;td&gt;20.4%&lt;/td&gt;
&lt;td&gt;19.1%&lt;/td&gt;
&lt;td&gt;0.76&lt;/td&gt;
&lt;td&gt;31.6&lt;/td&gt;
&lt;td&gt;3.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;MRK&lt;/td&gt;
&lt;td&gt;+64.5%&lt;/td&gt;
&lt;td&gt;+20.0%&lt;/td&gt;
&lt;td&gt;37.1%&lt;/td&gt;
&lt;td&gt;11.9%&lt;/td&gt;
&lt;td&gt;0.23&lt;/td&gt;
&lt;td&gt;115.1&lt;/td&gt;
&lt;td&gt;2.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;NEM&lt;/td&gt;
&lt;td&gt;+44.4%&lt;/td&gt;
&lt;td&gt;+30.2%&lt;/td&gt;
&lt;td&gt;45.6%&lt;/td&gt;
&lt;td&gt;15.8%&lt;/td&gt;
&lt;td&gt;0.54&lt;/td&gt;
&lt;td&gt;15.9&lt;/td&gt;
&lt;td&gt;2.23&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;JNJ&lt;/td&gt;
&lt;td&gt;+49.4%&lt;/td&gt;
&lt;td&gt;+12.0%&lt;/td&gt;
&lt;td&gt;25.5%&lt;/td&gt;
&lt;td&gt;8.6%&lt;/td&gt;
&lt;td&gt;0.24&lt;/td&gt;
&lt;td&gt;30.8&lt;/td&gt;
&lt;td&gt;2.15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;LLY&lt;/td&gt;
&lt;td&gt;+60.6%&lt;/td&gt;
&lt;td&gt;−3.8%&lt;/td&gt;
&lt;td&gt;33.0%&lt;/td&gt;
&lt;td&gt;20.4%&lt;/td&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;td&gt;37.5&lt;/td&gt;
&lt;td&gt;2.09&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;COP&lt;/td&gt;
&lt;td&gt;+35.6%&lt;/td&gt;
&lt;td&gt;+19.9%&lt;/td&gt;
&lt;td&gt;29.3%&lt;/td&gt;
&lt;td&gt;7.5%&lt;/td&gt;
&lt;td&gt;0.13&lt;/td&gt;
&lt;td&gt;18.2&lt;/td&gt;
&lt;td&gt;1.95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;XOM&lt;/td&gt;
&lt;td&gt;+44.6%&lt;/td&gt;
&lt;td&gt;+14.0%&lt;/td&gt;
&lt;td&gt;25.5%&lt;/td&gt;
&lt;td&gt;17.5%&lt;/td&gt;
&lt;td&gt;0.06&lt;/td&gt;
&lt;td&gt;21.3&lt;/td&gt;
&lt;td&gt;1.91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;ABBV&lt;/td&gt;
&lt;td&gt;+17.4%&lt;/td&gt;
&lt;td&gt;+15.2%&lt;/td&gt;
&lt;td&gt;29.2%&lt;/td&gt;
&lt;td&gt;10.5%&lt;/td&gt;
&lt;td&gt;0.28&lt;/td&gt;
&lt;td&gt;72.4&lt;/td&gt;
&lt;td&gt;1.85&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Bottom 10 by composite score
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ticker&lt;/th&gt;
&lt;th&gt;Momentum 12-1&lt;/th&gt;
&lt;th&gt;3m ret&lt;/th&gt;
&lt;th&gt;Ann. vol&lt;/th&gt;
&lt;th&gt;ROA&lt;/th&gt;
&lt;th&gt;Beta&lt;/th&gt;
&lt;th&gt;P/E&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;KLAC&lt;/td&gt;
&lt;td&gt;+119.2%&lt;/td&gt;
&lt;td&gt;−25.0%&lt;/td&gt;
&lt;td&gt;76.7%&lt;/td&gt;
&lt;td&gt;20.8%&lt;/td&gt;
&lt;td&gt;1.44&lt;/td&gt;
&lt;td&gt;49.2&lt;/td&gt;
&lt;td&gt;−2.33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BA&lt;/td&gt;
&lt;td&gt;+4.7%&lt;/td&gt;
&lt;td&gt;−5.0%&lt;/td&gt;
&lt;td&gt;33.2%&lt;/td&gt;
&lt;td&gt;−2.0%&lt;/td&gt;
&lt;td&gt;1.21&lt;/td&gt;
&lt;td&gt;75.7&lt;/td&gt;
&lt;td&gt;−2.35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QCOM&lt;/td&gt;
&lt;td&gt;+3.6%&lt;/td&gt;
&lt;td&gt;−9.9%&lt;/td&gt;
&lt;td&gt;48.4%&lt;/td&gt;
&lt;td&gt;11.6%&lt;/td&gt;
&lt;td&gt;1.68&lt;/td&gt;
&lt;td&gt;20.8&lt;/td&gt;
&lt;td&gt;−2.39&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ISRG&lt;/td&gt;
&lt;td&gt;−12.0%&lt;/td&gt;
&lt;td&gt;−10.6%&lt;/td&gt;
&lt;td&gt;47.4%&lt;/td&gt;
&lt;td&gt;10.5%&lt;/td&gt;
&lt;td&gt;1.47&lt;/td&gt;
&lt;td&gt;42.4&lt;/td&gt;
&lt;td&gt;−2.56&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NKE&lt;/td&gt;
&lt;td&gt;−43.3%&lt;/td&gt;
&lt;td&gt;−19.1%&lt;/td&gt;
&lt;td&gt;31.9%&lt;/td&gt;
&lt;td&gt;7.0%&lt;/td&gt;
&lt;td&gt;1.11&lt;/td&gt;
&lt;td&gt;17.5&lt;/td&gt;
&lt;td&gt;−2.73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CE&lt;/td&gt;
&lt;td&gt;−5.3%&lt;/td&gt;
&lt;td&gt;−10.7%&lt;/td&gt;
&lt;td&gt;40.3%&lt;/td&gt;
&lt;td&gt;2.6%&lt;/td&gt;
&lt;td&gt;0.76&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;−2.90&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LULU&lt;/td&gt;
&lt;td&gt;−27.9%&lt;/td&gt;
&lt;td&gt;−18.8%&lt;/td&gt;
&lt;td&gt;52.1%&lt;/td&gt;
&lt;td&gt;14.4%&lt;/td&gt;
&lt;td&gt;0.86&lt;/td&gt;
&lt;td&gt;8.1&lt;/td&gt;
&lt;td&gt;−2.96&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TSLA&lt;/td&gt;
&lt;td&gt;−7.8%&lt;/td&gt;
&lt;td&gt;−8.4%&lt;/td&gt;
&lt;td&gt;56.2%&lt;/td&gt;
&lt;td&gt;1.9%&lt;/td&gt;
&lt;td&gt;1.85&lt;/td&gt;
&lt;td&gt;332.2&lt;/td&gt;
&lt;td&gt;−3.91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ORCL&lt;/td&gt;
&lt;td&gt;−48.7%&lt;/td&gt;
&lt;td&gt;−18.1%&lt;/td&gt;
&lt;td&gt;55.8%&lt;/td&gt;
&lt;td&gt;6.4%&lt;/td&gt;
&lt;td&gt;1.73&lt;/td&gt;
&lt;td&gt;23.5&lt;/td&gt;
&lt;td&gt;−4.55&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FMC&lt;/td&gt;
&lt;td&gt;−72.5%&lt;/td&gt;
&lt;td&gt;+1.9%&lt;/td&gt;
&lt;td&gt;66.8%&lt;/td&gt;
&lt;td&gt;0.6%&lt;/td&gt;
&lt;td&gt;0.42&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;−4.77&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  4. Read-through
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Energy refiners and majors&lt;/strong&gt; (VLO, MPC, PSX, COP, XOM) dominate the top of the ranking — strong 12-1 momentum, low beta, and solid ROA.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semis are split:&lt;/strong&gt; NVDA and MU rank high on momentum, but KLAC, QCOM, and INTC land in the bottom half on recent 3-month weakness and elevated volatility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defensive quality&lt;/strong&gt; (MA, V, JNJ, MRK, LLY) scores well on the low-vol / high-ROA / low-beta leg even with modest momentum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bottom of the table&lt;/strong&gt; is dominated by names with negative 3-month returns and/or negative ROA (BA, FMC, ORCL, NKE, LULU).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Reproducibility
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prices: &lt;code&gt;yfinance&lt;/code&gt; 2y daily adjusted close, 81 tickers.&lt;/li&gt;
&lt;li&gt;Fundamentals: &lt;code&gt;yfinance&lt;/code&gt; &lt;code&gt;.info&lt;/code&gt; (trailingPE, marketCap, returnOnAssets, beta).&lt;/li&gt;
&lt;li&gt;Factor math and scoring: pure pandas/numpy, no proprietary data.&lt;/li&gt;
&lt;li&gt;Full per-name factor table: &lt;code&gt;factor_scores.csv&lt;/code&gt; (81 rows × 9 columns).&lt;/li&gt;
&lt;li&gt;Raw prices: &lt;code&gt;prices_2y.csv&lt;/code&gt; (501 trading days × 81 tickers).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;LaunchTower&lt;/strong&gt; — independent market-data research. Not investment advice.&lt;/p&gt;

</description>
      <category>data</category>
      <category>finance</category>
      <category>python</category>
      <category>trading</category>
    </item>
    <item>
      <title>LaunchTower Factor Screen — 2026-09-15: The AI Trade Rotates From Equipment to Components</title>
      <dc:creator>penny penguin</dc:creator>
      <pubDate>Mon, 14 Sep 2026 02:56:41 +0000</pubDate>
      <link>https://dev.to/penny_penguin_199601ef2a7/launchtower-factor-screen-2026-09-15-the-ai-trade-rotates-from-equipment-to-components-j82</link>
      <guid>https://dev.to/penny_penguin_199601ef2a7/launchtower-factor-screen-2026-09-15-the-ai-trade-rotates-from-equipment-to-components-j82</guid>
      <description>&lt;h1&gt;
  
  
  LaunchTower Factor Screen — 2026-09-15: The AI Trade Rotates From Equipment to Components
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;By LaunchTower&lt;/strong&gt; · 5 min read · &lt;a href="https://github.com/pennypenguinapp-beep/launchtower-factor-datasets/blob/main/reports/launchtower_research_report_2026-09-15.md" rel="noopener noreferrer"&gt;Full report&lt;/a&gt; · &lt;a href="https://raw.githubusercontent.com/pennypenguinapp-beep/launchtower-factor-datasets/main/data/factor_scores_2026-09-15.csv" rel="noopener noreferrer"&gt;Raw data (CSV)&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Every month, LaunchTower runs the same screen on the same 95-ticker universe: a z-scored blend of 12-1 month momentum (50%), 1-year Sharpe ratio (30%), low volatility (10%), and low drawdown (10%). No discretion, no narrative, no "this time is different."&lt;/p&gt;

&lt;p&gt;This month, the screen told us something concrete: &lt;strong&gt;the AI trade has rotated from semiconductor equipment to semiconductor components.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed since 2026-09-14
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ticker&lt;/th&gt;
&lt;th&gt;Prior rank&lt;/th&gt;
&lt;th&gt;New rank&lt;/th&gt;
&lt;th&gt;What it makes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MU&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;HBM memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LITE&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Optical transceivers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WDC&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Nearline storage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;STX&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Nearline storage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INTC&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;CPUs / foundry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AMAT&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Semi equipment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TER&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Test equipment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MRVL&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Custom AI silicon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COHR&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Optical components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AMD&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;GPUs / CPUs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Six of the top 10 are &lt;strong&gt;new entrants&lt;/strong&gt; since last month. The names that fell out of the top 10 (LRCX, MPC, ASML, CAT, KLAC, FDX) are equipment makers, energy, and industrials — names that were leading the screen three weeks ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;The AI capex cycle is now showing up in the P&amp;amp;Ls of the names that actually &lt;strong&gt;ship&lt;/strong&gt; the HBM, transceivers, and nearline drives that data centers consume. Equipment makers (AMAT, LRCX, KLAC) remain in the top half of the screen but have lost their top-10 positions. The money is rotating from the pick-and-shovel names to the shovel names.&lt;/p&gt;

&lt;p&gt;Micron's +549% 12-month return is the single largest contributor to its #1 score. Lumentum's +462% run is the second-largest, driven by 800G/1.6T optical transceiver demand for AI clusters. Western Digital and Seagate — the two nearline storage leaders — are both in the top 4 for the first time in this screen's history.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bottom of the table
&lt;/h2&gt;

&lt;p&gt;The weakest risk-adjusted profiles in the universe are a mix of consumer software (HubSpot, Intuit, Trade Desk), gaming (Roblox), China-exposed names (Tencent Music, Grab), and high-beta crypto-adjacent (MicroStrategy). All 10 carry negative 12-month returns and negative Sharpe ratios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology (reproducible)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yfinance&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Fetch 2y daily closes for the 95-ticker universe
# 2. Compute:
#    - 12-1 momentum: close[-22] / close[-252] - 1
#    - Annualized vol: std(daily_returns, 252d) * sqrt(252)
#    - Sharpe: mean(daily_returns, 252d) * 252 / annualized_vol
#    - Max drawdown: min(close / cummax(close) - 1) over 252d
# 3. Z-score each component across the universe
# 4. Composite = 0.50*z_mom + 0.30*z_sharpe + 0.10*z_lowvol + 0.10*z_lowdd
# 5. Sort descending
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Data source:&lt;/strong&gt; Yahoo Finance (yfinance), auto-adjusted daily closes, trailing 2 years.&lt;br&gt;
&lt;strong&gt;Universe:&lt;/strong&gt; 95 liquid US mega-cap equities (tech, semis, industrials, energy, consumer).&lt;br&gt;
&lt;strong&gt;As-of date:&lt;/strong&gt; 2026-09-11 close (latest available at time of writing).&lt;/p&gt;

&lt;h2&gt;
  
  
  Full report and raw data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Report:&lt;/strong&gt; &lt;a href="https://github.com/pennypenguinapp-beep/launchtower-factor-datasets/blob/main/reports/launchtower_research_report_2026-09-15.md" rel="noopener noreferrer"&gt;launchtower_research_report_2026-09-15.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raw factor scores (CSV):&lt;/strong&gt; &lt;a href="https://raw.githubusercontent.com/pennypenguinapp-beep/launchtower-factor-datasets/main/data/factor_scores_2026-09-15.csv" rel="noopener noreferrer"&gt;factor_scores_2026-09-15.csv&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/pennypenguinapp-beep/launchtower-factor-datasets" rel="noopener noreferrer"&gt;github.com/pennypenguinapp-beep/launchtower-factor-datasets&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get the full model pack
&lt;/h2&gt;

&lt;p&gt;Want the complete, reproducible model — the full 95-ticker factor table, the dated research report, the exact Python code, and the methodology documentation — in one place?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://buy.stripe.com/test_dRmcN41Qj33N9964nf7AK3B" rel="noopener noreferrer"&gt;→ Get the LaunchTower Full Model Pack ($49)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What's included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The complete 95-ticker factor score dataset (CSV) from the 2026-09-15 screen&lt;/li&gt;
&lt;li&gt;The full dated research report with top/bottom 10 analysis and interpretation&lt;/li&gt;
&lt;li&gt;The self-contained Python script that reproduces the entire screen end-to-end&lt;/li&gt;
&lt;li&gt;Methodology documentation: component definitions, weights, z-scoring, and data sources&lt;/li&gt;
&lt;li&gt;CSV schema reference for every column&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One-time purchase. No subscription. No lock-in. Run it, verify it, build on it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;LaunchTower is a self-funded research desk. This post is for informational purposes only and does not constitute investment advice, a solicitation, or a recommendation to buy or sell any security. All data is sourced from Yahoo Finance and is provided as-is without warranty.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>finance</category>
      <category>data</category>
      <category>trading</category>
      <category>python</category>
    </item>
  </channel>
</rss>
