<?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: Batıkan Bayrak</title>
    <description>The latest articles on DEV Community by Batıkan Bayrak (@batikanbayrak).</description>
    <link>https://dev.to/batikanbayrak</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%2F4226878%2Fd8d487d7-18d0-4f17-a9c0-b82c869a3bc6.png</url>
      <title>DEV Community: Batıkan Bayrak</title>
      <link>https://dev.to/batikanbayrak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/batikanbayrak"/>
    <language>en</language>
    <item>
      <title>What do 90 days of our own logs say about turning trading signals into orders?</title>
      <dc:creator>Batıkan Bayrak</dc:creator>
      <pubDate>Wed, 04 Nov 2026 17:28:50 +0000</pubDate>
      <link>https://dev.to/batikanbayrak/what-do-90-days-of-our-own-logs-say-about-turning-trading-signals-into-orders-4ih5</link>
      <guid>https://dev.to/batikanbayrak/what-do-90-days-of-our-own-logs-say-about-turning-trading-signals-into-orders-4ih5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Over 90 days (Aug–Oct 2026), 8.5% of the Telegram channel messages our system read led to a trade action, and 4.3% of TradingView alerts opened an order. The rest was not lost: it was chat, duplicates, alerts sent while automation was off, or rules doing their job. Here is what that taught us as engineers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm the founder of AlgoVesta, a hosted service that takes signals people already follow (a Telegram channel, a TradingView alert or an AI assistant over MCP) and places them as orders on their own exchange or MetaTrader 5 account. Every decision the system makes is logged with a reason. This quarter we read those logs back, in a read-only database session, with our own monitoring account, test residue and deleted accounts removed, and any group of fewer than five users hidden. We did not look at profit and loss, and nothing below is a performance claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: 26.4% of the input is not a signal, so classification is the product
&lt;/h2&gt;

&lt;p&gt;The Telegram reader received 47288 channel messages for 72 customers across 182 channels in the window. 26.4% were classified as not a trading signal at all: conversation, result posts, charts without text. Another 65.1% were stopped before execution by a rule, a setting or a failure.&lt;/p&gt;

&lt;p&gt;The number we watch closest is much smaller. Messages that contain buy/sell, take-profit and stop-loss words but still could not be read as a signal were 0.2% of all messages, across 14 customers. Those are the silent failures: the customer believes a signal arrived, and nothing happens.&lt;/p&gt;

&lt;p&gt;What changed for us: a parse failure is now treated as an incident, not as noise. A message that looks like a signal and cannot be read lands in our incident view with the customer attached, so we see it before the customer has to ask.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 2: "blocked" is three different things, and only one is ours
&lt;/h2&gt;

&lt;p&gt;Of the Telegram messages that were stopped, 48.9% were stopped by a rule or setting the customer controls (no bot configured for that account, a channel outside the bot's scope, a daily limit), 48.4% were routine filtering such as duplicates, and 2.0% were attributed to a failure on our side.&lt;/p&gt;

&lt;p&gt;If you put those into one "failed" counter, the alert becomes useless within weeks, because the customer-controlled share swamps the real faults. We keep three buckets: policy (the customer can fix it and is told how), ours (an internal alert, never sent to the customer as "your setting"), and normal (not counted). An unknown reason code is never shown to a customer as their fault.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 3: webhooks arrive when you least expect them
&lt;/h2&gt;

&lt;p&gt;10755 TradingView webhook alerts reached us from 11 customers. 53.5% arrived while automatic trading was switched off for that strategy, 29.5% were duplicates and 12.2% were blocked or failed. Of the blocked ones, 56.5% hit a disabled webhook and 27.2% had a body we could not parse, usually a template with unfilled placeholders.&lt;/p&gt;

&lt;p&gt;Two engineering consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Idempotency is not optional.&lt;/strong&gt; Alert platforms retry, users duplicate alerts, and strategies fire the same condition twice. A duplicate must be recognised and logged, never executed a second time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The sender cannot sign requests.&lt;/strong&gt; TradingView alerts cannot carry custom HTTP headers, so an HMAC signature header will never arrive. Requiring one turns every alert into a 401. Source verification has to work another way: a long secret URL plus the sender's known IP addresses, or the customer's own allowlist. If none of those check out, the signal is logged and no order is placed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lesson 4: publish the distribution, not the best case
&lt;/h2&gt;

&lt;p&gt;For MT5 we record the round-trip of each order command, from sending it to the terminal until the terminal confirms. Across 1579 orders on live broker servers the median was 1.25 s and the 90th percentile 2.86 s. On demo servers it was 0.8 s across 2295 orders.&lt;/p&gt;

&lt;p&gt;Our earlier public number was a single end-to-end demo order at 849 ms. It was true, but it was one order on a demo server. Live servers are slower and the spread is wider. We now publish the median and the 90th percentile, with the server type, and we keep the old single measurement labelled for what it was.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 5: a protective order is only real if the venue confirms it
&lt;/h2&gt;

&lt;p&gt;Of the MT5 positions we opened, 100.0% had a stop-loss and 100.0% had a take-profit recorded on the position, on live servers (1579 positions) and on demo servers (2295 positions). On live crypto futures accounts, 76 of 76 positions had an exchange-confirmed stop-loss recorded.&lt;/p&gt;

&lt;p&gt;The design choice behind that: a forex order without both a stop-loss and a take-profit is not sent, and on crypto the stop-loss written to our records comes from the exchange's confirmation alone, not from what was requested. If a stop cannot be confirmed, the position we just opened is closed again seconds later rather than left unprotected. Before execution, Telegram signals were refused 353 times because a stop-loss and take-profit could not be ensured.&lt;/p&gt;

&lt;p&gt;For context, in the same MT5 accounts, positions not opened by our system had a stop-loss in 65.4% of cases on live servers and 27.3% on demo servers. That is not a judgement of those traders; it is a reminder that "the platform supports stops" and "every position has one" are different statements.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we found in our own records
&lt;/h2&gt;

&lt;p&gt;Reading the logs back exposed gaps we had not noticed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On live crypto accounts, 81.2% of closes were detected on the exchange without a recorded cause (stop, target or manual).&lt;/li&gt;
&lt;li&gt;For live crypto orders that came through Telegram, the link from message to order is not stored, so we could not measure live crypto timing this quarter.&lt;/li&gt;
&lt;li&gt;Our record of unprotected MT5 positions has no field that tells us when a case was resolved, so "how fast was it fixed" cannot be answered from it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these change what a customer's account does. All three change what we can prove, which is why they are on the list for next quarter's measurement.&lt;/p&gt;

&lt;p&gt;Status on 1 November 2026, after we changed the records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixed: close causes for live crypto accounts are now classified from the exchange's own trade records. Of the 65 live closes in the window, 7 were stops, 6 targets, 5 liquidations and 19 manual closes in the exchange's own app; 16 remain unknown and 12 could not be checked.&lt;/li&gt;
&lt;li&gt;Fixed: the unprotected-MT5 record now stores how each case ended. 38 of the 40 past cases were resolved from our own data (36 closed, 2 protected).&lt;/li&gt;
&lt;li&gt;Change deployed, first live record still pending: Telegram crypto orders now store the message that opened them. We will report timing once real orders carry the link.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This is our own customer base, not the market; people who pick an automation tool differ from traders in general.&lt;/li&gt;
&lt;li&gt;Deleted accounts are excluded and some customers left during the window (survivorship).&lt;/li&gt;
&lt;li&gt;Crypto testnet and MT5 demo servers are labelled, not blended with live.&lt;/li&gt;
&lt;li&gt;The MT5 login log starts on 2026-08-12.&lt;/li&gt;
&lt;li&gt;Close reasons are not profits. We do not publish win rates or returns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About the author
&lt;/h2&gt;

&lt;p&gt;Batıkan Bayrak is the founder and developer of AlgoVesta, a hosted execution layer for Telegram, TradingView and MCP signals on 16 crypto exchanges + MetaTrader 5. I'm the founder of AlgoVesta, so read this with that interest in mind.&lt;/p&gt;

&lt;p&gt;Full data study, method and tables: &lt;a href="https://algovesta.com/blog/signal-to-trade-90-days-data-2026.html" rel="noopener noreferrer"&gt;https://algovesta.com/blog/signal-to-trade-90-days-data-2026.html&lt;/a&gt;&lt;br&gt;
How the system handles accounts and orders: &lt;a href="https://algovesta.com/how-it-works.html" rel="noopener noreferrer"&gt;https://algovesta.com/how-it-works.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algotrading</category>
      <category>mcp</category>
      <category>observability</category>
      <category>python</category>
    </item>
  </channel>
</rss>
