') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - divergex/dxforge · GitHub
Skip to content

Repository files navigation

dxforge icon, an anvil dxforge

dxforge is the orchestration suite within the Divergex ecosystem, designed to enable seamless service discovery, secure communication, and containerized infrastructure management for high-performance quantitative research and trading systems.

It is basically just a multi-tenant scheduling serverless platform, but self-hosted on your own infrastructure.

Main Usage

Orchestration

The main purpose of dxforge is to use it to orchestrate and schedule of processes. Suppose you have a small prop trading setup, for a retailer or family member, or even a small desk at a trading firm.

We believe that everyone should be able to run their own trading infrastructure, and dxforge is the tool to help you start with that. At some point, you will want a more robust setup to organize your strategies (or strategy! dxforge is aimed to both the small and large investors).

Service Discovery

Moved to dxlib.

Containerization

  • Different users have different needs, and dxforge aims to allows you to run your services in isolated containers, on host or on isolated processes, ensuring that dependencies and configurations do not conflict depending on your needs.
  • Works with Docker and (in future also Kubernetes and Podman) to deploy, manage, and scale services.

Features

We aim mainly to have dxforge provide the following for all levels of users, and are our main requiisites for all future features

  • Scalability: Easily scale services up and down based or num of strategies.
  • Fault Tolerance: Incorporate resiliency features like retries, fallbacks, and circuit breakers.
  • Interoperability: At some point support full integration with other components of the divergex ecosystem, including cadlag and dxlib.

Installation

Prerequisites

  • Python 3.x
  • Or git if you want to clone the repository directly.

Getting Started

Installing with pip:

pip install dxforge # TODO

Cloning the repository:

git clone https://github.com/divergex/dxforge.git
cd dxforge

Create an environment and install locally with

conda create -n dxforge python=3.12
conda activate dxforge
pip install -e .

You should now be able to run tests and also the CLI with

forge --help

Usage

Once set up, you can configure your services to interact via dxforge for service discovery, mesh registration, and secure communication. To enable these features:

  1. Service Registration: Register services with the built-in discovery mechanism.
  2. Inter-Service Communication: Utilize the provided protocols and channels for secure messaging.
  3. Scaling: Leverage Kubernetes or Docker Swarm to scale services automatically based on load.

Start the api and access it at http://localhost:8000 with

forge api run

Contributing

If you'd like to contribute to the development of dxforge, see the CONTRIBUTING guidelines for details on how to get started.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages