Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,25 @@ if(OPTIONX_BUILD_EXAMPLES)
endif()
target_link_libraries(telegram_signal_bridge_smoke PRIVATE ${EXAMPLE_LIBS} optionx_cpp)

add_executable(telegram_archive_parser_smoke examples/telegram_archive_parser_smoke.cpp)
target_compile_features(telegram_archive_parser_smoke PRIVATE cxx_std_17)
target_include_directories(telegram_archive_parser_smoke PRIVATE
${EXAMPLE_INCLUDE_DIRS}
${EXAMPLE_DEPS_INCLUDE_DIRS}
)
target_link_directories(telegram_archive_parser_smoke PRIVATE ${EXAMPLE_LIBRARY_DIRS})
target_compile_definitions(
telegram_archive_parser_smoke PRIVATE
${EXAMPLE_DEFINES}
LOGIT_BASE_PATH="${LOGIT_BASE_PATH_FWD}"
)
if(MINGW)
target_compile_options(telegram_archive_parser_smoke PRIVATE -Wa,-mbig-obj)
elseif(MSVC)
target_compile_options(telegram_archive_parser_smoke PRIVATE /bigobj)
endif()
target_link_libraries(telegram_archive_parser_smoke PRIVATE ${EXAMPLE_LIBS} optionx_cpp)

add_executable(protocol_v1_bridge_smoke examples/protocol_v1_bridge_smoke.cpp)
target_compile_features(protocol_v1_bridge_smoke PRIVATE cxx_std_17)

Expand Down
4 changes: 4 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ Currently maintained examples:
bridge lifecycle with a deterministic in-memory source. The production
source boundary can be backed by `tg-client-stdio`; this example needs no
Telegram credentials.
- `telegram_archive_parser_smoke.cpp` replays exported Telegram raw-message
records through the parser and keeps executable signals, outcomes and
diagnostics separate. It uses deterministic fixtures and needs no Telegram
credentials.
- `metatrader_file_bridge_smoke.cpp` runs the C++ side of the MetaTrader
Common\Files bridge against a temporary command/event layout.
- `metatrader_file_command_writer_smoke.cpp` demonstrates the C++ command-writer
Expand Down
81 changes: 81 additions & 0 deletions examples/telegram_archive_parser_smoke.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/// \file telegram_archive_parser_smoke.cpp
/// \brief Demonstrates replaying exported Telegram messages through the parser.

#include <optionx_cpp/bridges/telegram.hpp>

#include <cstdint>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

namespace {

optionx::bridges::telegram::TelegramRawMessage make_message(
std::int64_t message_id,
std::string text,
std::int64_t reply_to_message_id = 0);

std::vector<optionx::bridges::telegram::TelegramRawMessage> demo_archive();

void print_parsed(
const optionx::bridges::telegram::TelegramParsedMessage& parsed);

} // namespace

int main() {
// In production these records arrive one at a time from
// tg-client-stdio::WorkerClient::stream_messages(). Keeping the replay
// loop source-independent makes parser tests and backtests deterministic.
optionx::bridges::telegram::TelegramSignalParser parser;
for (const auto& raw : demo_archive()) {
print_parsed(parser.parse(raw));
}
return 0;
}

namespace {

optionx::bridges::telegram::TelegramRawMessage make_message(
const std::int64_t message_id,
std::string text,
const std::int64_t reply_to_message_id) {
optionx::bridges::telegram::TelegramRawMessage message;
message.chat_id = "-1001234567890";
message.chat_title = "Demo archive";
message.message_id = message_id;
message.date_ms = 1800000000000 + message_id * 1000;
message.reply_to_message_id = reply_to_message_id;
message.text = std::move(text);
return message;
}

std::vector<optionx::bridges::telegram::TelegramRawMessage> demo_archive() {
return {
make_message(100, "EURUSD BUY 5m"),
make_message(101, "EURUSD WIN", 100),
make_message(102, "USDJPY BUY 2 weeks"),
};
}

void print_parsed(
const optionx::bridges::telegram::TelegramParsedMessage& parsed) {
std::cout << "message=" << parsed.raw.message_identity()
<< " signals=" << parsed.signals.size()
<< " outcomes=" << parsed.outcomes.size()
<< " diagnostics=" << parsed.diagnostics.size() << '\n';
for (const auto& signal : parsed.signals) {
std::cout << " signal=" << signal.symbol
<< " direction=" << optionx::to_str(signal.order_type)
<< " duration=" << signal.duration << '\n';
}
for (const auto& outcome : parsed.outcomes) {
std::cout << " outcome=" << outcome.symbol
<< " result=" << static_cast<int>(outcome.result) << '\n';
}
for (const auto& diagnostic : parsed.diagnostics) {
std::cout << " diagnostic=" << diagnostic.code << '\n';
}
}

} // namespace
15 changes: 10 additions & 5 deletions guides/telegram-bridge-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ stdio boundary.

The current OptionX bridge does not own a Telethon process. It consumes the
`TelegramMessageSource` interface, so fake sources can exercise parsing and
lifecycle without credentials. The concrete source adapter will bind that
interface to `tg-client-stdio::WorkerClient` after the worker repository's
supervisor and typed archive API are merged and pinned by OptionX.
lifecycle without credentials. `TelegramWorkerMessageSource` now binds that
interface to a WorkerClient-shaped process adapter; the parent repository will
pin the concrete `tg-client-stdio::WorkerClient` only after its stacked worker
PRs are merged.

## Stdio Protocol Envelope

Expand Down Expand Up @@ -332,13 +333,17 @@ Completed without an authorized Telegram session:
source-independent `TelegramSignalBridge`.
4. Fake-source unit coverage and a runnable no-credentials bridge example.

Current no-credentials examples include a live fake-source bridge smoke and a
deterministic archive/parser replay. The latter uses the same raw-message shape
that `messages.export` streams, while keeping parser outcomes separate from
executable signals.

Next steps:

1. Merge and pin the worker repository's supervisor/archive PRs.
2. Pin the merged worker repository in an OptionX consumer and run the adapter
against the mock worker process.
3. Add a historical archive/parser fixture example.
4. Perform the first real authorization, proxy and live-channel check with an
3. Perform the first real authorization, proxy and live-channel check with an
operator-provided Telegram session.

OCR/vision remains a separate optional provider and should not block the text
Expand Down
Loading