<?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: Artem</title>
    <description>The latest articles on DEV Community by Artem (@depthsight).</description>
    <link>https://dev.to/depthsight</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%2F3971092%2F30efb8b4-e191-4c1a-aaee-1e2440363543.png</url>
      <title>DEV Community: Artem</title>
      <link>https://dev.to/depthsight</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/depthsight"/>
    <language>en</language>
    <item>
      <title>How I built a self-hosted Algorithmic Trading Ecosystem (and why it's Open Source)</title>
      <dc:creator>Artem</dc:creator>
      <pubDate>Fri, 19 Jun 2026 13:37:53 +0000</pubDate>
      <link>https://dev.to/depthsight/how-i-built-a-self-hosted-algorithmic-trading-saas-and-why-its-open-source-2j22</link>
      <guid>https://dev.to/depthsight/how-i-built-a-self-hosted-algorithmic-trading-saas-and-why-its-open-source-2j22</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Don't want to read the story? I open-sourced my self-hosted visual engine for algorithmic trading (280k LOC). &lt;br&gt;
📦 &lt;strong&gt;&lt;a href="https://github.com/DepthSight-Pro/DepthSight" rel="noopener noreferrer"&gt;View Source Code on GitHub&lt;/a&gt;&lt;/strong&gt; | 🌐 &lt;strong&gt;&lt;a href="https://depthsight.pro" rel="noopener noreferrer"&gt;Official Website&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction: The Problem with Centralized SaaS Bots
&lt;/h2&gt;

&lt;p&gt;If you've ever dabbled in algorithmic crypto trading, you've likely encountered two fundamental problems with existing SaaS solutions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first pain point is security.&lt;/strong&gt; The architectural absurdity of the modern industry is that users willingly hand over their API keys (often linked to massive balances) to third-party, closed-source servers. A database leak in such a service isn't just a leak of email addresses; it's direct access to user deposits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The second pain point is primitive logic.&lt;/strong&gt; Most paid solutions offer little more than basic Grid or DCA strategies. The moment you need flexibility—for example, pegging a stop-loss to an order book density, using a trailing stop that only activates after a level breakout, or dynamically filtering trades based on a higher timeframe trend—you hit the hard limits of their interface.&lt;/p&gt;

&lt;p&gt;Ultimately, all of this pushed me to build my own project: &lt;strong&gt;DepthSight&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My goal was to create a self-hosted platform featuring around 40 logical blocks (order book, tape, levels, volume delta, higher timeframe checks, etc.). These blocks can reference each other's results, allowing you to build highly complex event chains. I wanted a truly flexible strategy editor where a trader could visually implement their ideas without writing a single line of code. And if assembling blocks manually feels like too much work, the built-in AI Co-pilot will do it for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs051114f803lpq5rz2ba.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs051114f803lpq5rz2ba.gif" alt="Visual Strategy Editor" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Not Freqtrade, Jesse, or OctoBot?
&lt;/h2&gt;

&lt;p&gt;A fair question: why write your own if there are already trading bots in the open-source space?&lt;br&gt;
Indeed, there are powerful tools on the market:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Freqtrade&lt;/strong&gt; and &lt;strong&gt;Jesse&lt;/strong&gt; are magnificent frameworks. But they are built exclusively for developers and quants. You need to know how to write logic in Python, dig into config files, and manage everything via CLI. There is no visual interface for regular traders.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;OctoBot&lt;/strong&gt; has a web UI, but architecturally, it's geared towards local, personal use by a single individual. It lacks an advanced No-Code node builder and the infrastructure needed for scaling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The advantage of DepthSight&lt;/strong&gt; is that it takes the best of both worlds: the uncompromising power of quant frameworks and the visual comfort of top commercial SaaS solutions (like 3Commas or Bitsgap), while adding a social layer and advanced AI.&lt;/p&gt;


&lt;h2&gt;
  
  
  A Full-Fledged SaaS "in a Box"
&lt;/h2&gt;

&lt;p&gt;DepthSight isn't just a script you run in the terminal. It's a ready-to-use infrastructure product, a &lt;strong&gt;SaaS "in a box"&lt;/strong&gt; that you can deploy on your own server and immediately use to manage an investor pool or even launch your own commercial service.&lt;/p&gt;

&lt;p&gt;Right out of the box, the project features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Built-in Crypto Acquiring (BitCart):&lt;/strong&gt; Accept payments in BTC, LTC, TRX, BNB without intermediaries or fees.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Billing and Quota Manager:&lt;/strong&gt; Limit the number of bots, backtest threads, and available exchanges based on the user's subscription plan.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Full Admin Panel:&lt;/strong&gt; User management, Role-Based Access Control (RBAC), and a support ticket system.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Affiliate (Referral) Program:&lt;/strong&gt; A built-in hold tracker and automatic payout calculation for affiliates.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Gamification:&lt;/strong&gt; Experience points (XP), levels, and achievements to boost trader engagement.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Architecture: How It Works Under the Hood
&lt;/h2&gt;

&lt;p&gt;For the platform to handle heavy computations and run stably 24/7 in a multi-user environment, the architecture was designed from the ground up to be distributed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Tech Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Backend:&lt;/strong&gt; Python 3.11+, FastAPI (REST + WebSockets).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Connectors:&lt;/strong&gt; &lt;code&gt;ccxt&lt;/code&gt; for unified exchange interactions.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Asynchronous Tasks:&lt;/strong&gt; Celery (for heavy backtests and genetic optimization).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Frontend:&lt;/strong&gt; React / Vite / TypeScript (including a PWA for mobile).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Databases:&lt;/strong&gt; PostgreSQL (persistent storage) + Redis (state, quotas, Pub/Sub).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv7691y60edje26r7xlk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv7691y60edje26r7xlk.png" alt="DepthSight Architecture Diagram" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Architectural Magic: Market Data Fan-out
&lt;/h3&gt;

&lt;p&gt;One of the main bottlenecks in multi-user trading platforms is the strict exchange rate limits on WebSocket connections. If 50 users launch bots on the BTC/USDT pair, and each opens its own socket to the exchange, you'll get banned instantly.&lt;/p&gt;

&lt;p&gt;DepthSight implements a &lt;strong&gt;Market Data Fan-out&lt;/strong&gt; pattern. A single central service (&lt;code&gt;market_data_service.py&lt;/code&gt;) collects ticks and distributes them to all isolated worker containers via &lt;strong&gt;Redis Pub/Sub&lt;/strong&gt;.&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="c1"&gt;# market_data_service.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;redis.asyncio&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;redis_asyncio&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bot_module.exchanges&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_exchange_executor&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MarketDataService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_get_consumer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exchange_id&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="n"&gt;DataConsumer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Dynamically creates a CCXT-based connector for the required exchange.&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;exchange_id&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Universal executor for any exchange
&lt;/span&gt;            &lt;span class="n"&gt;futures_executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_exchange_executor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;exchange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;exchange_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&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;api_secret&lt;/span&gt;&lt;span class="o"&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;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;market_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;futures_usdtm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DataConsumer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;futures_executor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;market_data_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;direct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;market_data_publish_callback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_publish_market_payload&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;exchange_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;consumer&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;consumers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;exchange_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_publish_market_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&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;Any&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;A single WebSocket connection receives data from CCXT 
        and broadcasts it to workers via Redis Pub/Sub.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;stream_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stream_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&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;depthsight:market_data:events:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stream_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="c1"&gt;# Publish tick to channel. Bots no longer need to ping the exchange.
&lt;/span&gt;        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This solution allows the platform to scale horizontally, serving hundreds of bots with zero additional load on the exchange API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Visual Engine and AI Co-pilot
&lt;/h2&gt;

&lt;p&gt;The DepthSight interface lets you build strategies using visual blocks (nodes). But the real magic happens when a user employs the &lt;strong&gt;AI Co-pilot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A trader can write a prompt in natural language perfectly matching the visual editor's capabilities:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Create a strategy: go long on the breakout of the local high on the 15-minute timeframe, confirm with a spike in volume delta. Set the stop-loss 0.5% below the nearest large order book density, and make the take-profit floating (trailing) with a 1% activation step."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The neural network generates a ready-to-use node tree from this request.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Hallucination Protection (Structured Outputs)
&lt;/h3&gt;

&lt;p&gt;To prevent the LLM from outputting broken JSON, the backend strictly controls the neural network's output using &lt;strong&gt;Pydantic&lt;/strong&gt;:&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="c1"&gt;# api/schemas.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GenerateStrategyRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;text_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(...,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Text description of the strategy from the user.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;current_config_json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Dict&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;Any&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Current configuration for modification.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StrategyV2ConfigData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;strategy_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VisualBuilderStrategy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;marketType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FUTURES&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ConditionNode&lt;/span&gt;
    &lt;span class="n"&gt;entryConditions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ConditionNode&lt;/span&gt;
    &lt;span class="n"&gt;positionManagement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ManagementBlock&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;oracle_regime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;use_ml_confirmation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="c1"&gt;# api/routes/ai.py
&lt;/span&gt;&lt;span class="nd"&gt;@ai_core_router.post&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-strategy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;response_model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;schemas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApiResponseData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;schemas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StrategyV2ConfigData&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_strategy_from_text_ai_core_endpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;schemas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenerateStrategyRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_current_user&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# LLM (Gemini/OpenRouter) generates JSON.
&lt;/span&gt;    &lt;span class="c1"&gt;# Pydantic strictly validates the response via StrategyV2ConfigData
&lt;/span&gt;    &lt;span class="n"&gt;generated_json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ai_assistant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_strategy_json_from_prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Plus user permissions check (block availability based on their plan)
&lt;/span&gt;    &lt;span class="nf"&gt;enforce_strategy_plan_restrictions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generated_json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;generated_json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Federated Discovery Hub (The Social Layer)
&lt;/h2&gt;

&lt;p&gt;Trading entirely alone on your private server is secure, but it often lacks a fresh perspective. That's why the &lt;strong&gt;Discovery Hub&lt;/strong&gt; is built directly into the DepthSight monorepo.&lt;/p&gt;

&lt;p&gt;Even if you are a solo trader running a personal version of the platform on an isolated VPS, you can still be part of the global community. The platform uses a federated client-server model: your independent self-hosted instance can securely connect to the central community hub.&lt;/p&gt;

&lt;p&gt;No private keys, IP addresses, or balances ever leave your server. Users share only what they want to: logic (node trees) and beautiful PnL charts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Essentially, it's TradingView for algo-traders:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Strategy Sharing:&lt;/strong&gt; Like someone's result? One click on "Import", and the completed node tree is instantly copied to your local editor, ready to be launched or tweaked.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Social Mechanics:&lt;/strong&gt; It's not just a dry exchange of backtests. You can publish trade ideas, hypotheses, leave likes, and write comments.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Hive Mind:&lt;/strong&gt; Discuss drawdowns, share trailing stop settings, or filters for fake breakouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This forms a powerful network effect: the community hunts for "alpha" together and shares the best setups, yet the keys and deposits of every trader remain exclusively in their own pocket.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Deployment Experience
&lt;/h2&gt;

&lt;p&gt;I tried to make deployment as "one-click" as possible. The repository includes a &lt;code&gt;deploy.sh&lt;/code&gt; script. It automatically sets up the firewall (&lt;code&gt;ufw&lt;/code&gt;), spins up Docker, configures Caddy for automatic HTTPS, and safely generates all passwords:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Snippet from deploy.sh: Generating secure environment variables&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; .env &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"[*] Generating secure .env configuration..."&lt;/span&gt;
    &lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env

    &lt;span class="c"&gt;# Automatically create cryptographically strong secrets&lt;/span&gt;
    &lt;span class="nv"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 32&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;POSTGRES_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;openssl rand &lt;span class="nt"&gt;-hex&lt;/span&gt; 16&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;FERNET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"import os, base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s|JWT_SECRET_KEY=.*|JWT_SECRET_KEY=&lt;/span&gt;&lt;span class="nv"&gt;$JWT_SECRET&lt;/span&gt;&lt;span class="s2"&gt;|g"&lt;/span&gt; .env
    &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=&lt;/span&gt;&lt;span class="nv"&gt;$POSTGRES_PASS&lt;/span&gt;&lt;span class="s2"&gt;|g"&lt;/span&gt; .env
    &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"s|API_ENCRYPTION_KEY=.*|API_ENCRYPTION_KEY=&lt;/span&gt;&lt;span class="nv"&gt;$FERNET_KEY&lt;/span&gt;&lt;span class="s2"&gt;|g"&lt;/span&gt; .env
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't need to manually invent database passwords or salts for your JWTs. Everything is generated locally.&lt;/p&gt;




&lt;h2&gt;
  
  
  The "Solo + AI" Workflow: Scaling Beyond One Person
&lt;/h2&gt;

&lt;p&gt;One of the most frequent questions I get is: &lt;em&gt;"How did a single developer build a 280,000-line platform in less than a year?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The answer isn't "I let the AI do everything." The key is treating LLMs as an &lt;strong&gt;Architectural Force Multiplier&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;I focused on the high-level system design: the Market Data Fan-out pattern, the Pydantic validation layers, and the core trading logic. The AI handled the heavy lifting—generating over 1,100 unit tests, handling boilerplate for dozens of API endpoints, and prototyping React components. &lt;/p&gt;

&lt;p&gt;However, rapid AI-driven development has its trade-offs, primarily in the form of architectural "God Objects." While the business logic is robust and the security is tight, the boundaries between the API and the Engine are sometimes blurred. I see this as the next phase of the project: I’ve built a massive, functional core, and I’m now inviting the community to help refine, decouple, and optimize it.&lt;/p&gt;

&lt;h3&gt;
  
  
  OTA Updates (Over-The-Air) from the UI
&lt;/h3&gt;

&lt;p&gt;Maintaining a self-hosted instance is often a chore. To solve this, I implemented an OTA update system directly in the web interface. &lt;/p&gt;

&lt;p&gt;When a user clicks "Update" in the UI, the FastAPI backend creates a trigger file (&lt;code&gt;.update_trigger&lt;/code&gt;) in a shared volume. A host-side cron job detects this file and executes the &lt;code&gt;update.sh&lt;/code&gt; script, which pulls the latest code from GitHub and rebuilds the containers. This allows users to stay up-to-date without ever touching the terminal.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion and Monetization
&lt;/h2&gt;

&lt;p&gt;DepthSight is released under the &lt;strong&gt;GNU AGPL-3.0&lt;/strong&gt; license. This license gives you complete freedom to use, modify, and run the product for yourself. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I plan to monetize this?&lt;/strong&gt;&lt;br&gt;
I believe in transparent monetization. DepthSight is an official &lt;strong&gt;Bybit Broker Partner&lt;/strong&gt;. I’ve integrated my Broker ID directly into the executor code. When your bot trades on the platform, the exchange shares a small portion of its commission with me. Your trading conditions, fees, and spreads remain exactly the same—the exchange pays the fee, not you.&lt;/p&gt;

&lt;p&gt;This creates a win-win scenario: the software remains free and open-source, while the development is sustained by the platform's actual usage.&lt;/p&gt;

&lt;p&gt;The project is currently in Open Beta. In the future, I plan to expand our broker partnerships and refine the genetic optimization engine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're interested in the architecture of complex distributed systems, Python, React, or algorithmic trading—I would love your star on the repository or your Pull Requests!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/DepthSight-Pro/DepthSight/" rel="noopener noreferrer"&gt;https://github.com/DepthSight-Pro/DepthSight/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. Let me know in the comments which bots you currently use and why you do (or don't) trust them with your API keys.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>ai</category>
      <category>python</category>
    </item>
  </channel>
</rss>
