tektii


Nametektii JSON
Version 1.1.2 PyPI version JSON
download
home_pageNone
SummaryBuild trading strategies that run anywhere - Write Once. Trade Everywhere.
upload_time2025-08-04 10:15:27
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseApache-2.0
keywords trading algorithmic-trading algo-trading quantitative-finance finance fintech strategy backtesting grpc trading-bot trading-strategies market-data portfolio-management
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Tektii Python SDK

[![PyPI Version](https://img.shields.io/pypi/v/tektii)](https://pypi.org/project/tektii/)
[![Python Version](https://img.shields.io/pypi/pyversions/tektii)](https://pypi.org/project/tektii/)
[![License](https://img.shields.io/pypi/l/tektii)](https://github.com/tektii/tektii-sdk-python/blob/main/LICENSE)
[![Documentation](https://img.shields.io/badge/docs-latest-blue)](https://docs.tektii.com/sdk)
[![CI Status](https://img.shields.io/github/actions/workflow/status/tektii/tektii-sdk-python/ci.yml?branch=main)](https://github.com/tektii/tektii-sdk-python/actions)
[![Coverage](https://img.shields.io/codecov/c/github/tektii/tektii-sdk-python)](https://codecov.io/gh/tektii/tektii-sdk-python)

**Build trading strategies that run anywhere - Write Once. Trade Everywhere.**

The Tektii Python SDK provides a powerful, type-safe framework for building algorithmic trading strategies. Whether you're backtesting historical data or deploying to production, Tektii's event-driven architecture and comprehensive tooling help you focus on strategy development.

## ๐Ÿš€ Features

- **Event-Driven Architecture** - React to market data and order updates in real-time
- **Type-Safe Models** - Pydantic-powered models with full type hints and validation
- **Financial Precision** - Built-in Decimal support for accurate financial calculations
- **Fluent API** - Intuitive order builder with compile-time safety
- **Testing Framework** - Comprehensive test harness for strategy development
- **gRPC Integration** - High-performance communication with the Tektii Engine
- **Production Ready** - Deploy directly to Tektii's cloud infrastructure

## ๐Ÿ“ฆ Installation

### Requirements

- Python 3.11 or higher
- pip or poetry

### Install from PyPI

```bash
pip install tektii
```

### Install for Development

```bash
# Clone the repository
git clone https://github.com/tektii/tektii-sdk-python.git
cd tektii-sdk-python

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in development mode
make setup  # or: pip install -e ".[dev]"
```

## ๐ŸŽฏ Quick Start

### 1. Create Your First Strategy

```python
from decimal import Decimal
from typing import Optional

from tektii.strategy import TektiiStrategy
from tektii.strategy.models import BarData, OrderSide, OrderType, TickData


class MyStrategy(TektiiStrategy):
    """A simple moving average crossover strategy."""

    def __init__(self):
        super().__init__()
        self.position_size = Decimal("100")

    def on_market_data(
        self,
        tick_data: Optional[TickData] = None,
        bar_data: Optional[BarData] = None
    ) -> None:
        """React to incoming market data."""
        if bar_data and bar_data.close > Decimal("150.00"):
            # Create and submit a buy order
            order = (
                self.create_order()
                .symbol(bar_data.symbol)
                .side(OrderSide.BUY)
                .quantity(self.position_size)
                .order_type(OrderType.MARKET)
                .build()
            )
            self.submit_order(order)
```

### 2. Test Your Strategy

```python
from tektii.testing import StrategyTestHarness
from tektii.testing.fixtures import create_bar_data


def test_my_strategy():
    # Create test harness
    harness = StrategyTestHarness(MyStrategy)

    # Send test market data
    test_bar = create_bar_data(
        symbol="AAPL",
        close=Decimal("151.00")  # Above our threshold
    )
    harness.process_bar_data(test_bar)

    # Verify order was created
    orders = harness.get_orders()
    assert len(orders) == 1
    assert orders[0].side == OrderSide.BUY
```

### 3. Run Your Strategy

```bash
# Create a new strategy from template
tektii new my-strategy

# Test your strategy
tektii test

# Run strategy locally
tektii serve --port 50051

# Deploy to Tektii Cloud
tektii push
```

## ๐Ÿ“š Documentation

### Strategy Development

Your strategy should inherit from `TektiiStrategy` and implement the event handlers:

```python
class TektiiStrategy:
    def on_initialize(self, config: dict[str, str], symbols: list[str]) -> None:
        """Initialize strategy with configuration."""

    def on_market_data(self, tick_data: Optional[TickData], bar_data: Optional[BarData]) -> None:
        """Handle incoming market data."""

    def on_order_update(self, order_update: OrderUpdateEvent) -> None:
        """Handle order status updates."""

    def on_position_update(self, position_update: PositionUpdateEvent) -> None:
        """Handle position changes."""

    def on_account_update(self, account_update: AccountUpdateEvent) -> None:
        """Handle account updates."""

    def on_shutdown(self) -> None:
        """Clean up resources."""
```

### Order Management

Use the fluent order builder API for type-safe order creation:

```python
# Market order
market_order = (
    self.create_order()
    .symbol("AAPL")
    .side(OrderSide.BUY)
    .quantity(Decimal("100"))
    .order_type(OrderType.MARKET)
    .build()
)

# Limit order with time-in-force
limit_order = (
    self.create_order()
    .symbol("GOOGL")
    .side(OrderSide.SELL)
    .quantity(Decimal("50"))
    .order_type(OrderType.LIMIT)
    .limit_price(Decimal("2500.00"))
    .time_in_force(TimeInForce.GTC)
    .build()
)

# Stop-loss order
stop_order = (
    self.create_order()
    .symbol("MSFT")
    .side(OrderSide.SELL)
    .quantity(Decimal("200"))
    .order_type(OrderType.STOP)
    .stop_price(Decimal("380.00"))
    .build()
)
```

### Error Handling

The SDK provides specific exceptions for different error scenarios:

```python
from tektii.strategy.models.errors import (
    InvalidOrderError,
    ValidationError,
    BrokerConnectionError,
)

try:
    order = self.create_order().build()  # Missing required fields
except ValidationError as e:
    self.log_error(f"Order validation failed: {e}")
except BrokerConnectionError as e:
    self.log_error(f"Broker connection lost: {e}")
```

## ๐Ÿงช Testing

The SDK includes comprehensive testing utilities:

```bash
# Run all tests
make test

# Run specific test file
pytest tests/unit/models/test_orders.py

# Run with coverage
make test-coverage

# Run only fast tests
make test-fast
```

### Writing Tests

```python
import pytest
from decimal import Decimal
from tektii.testing import StrategyTestHarness


class TestMyStrategy:
    def test_strategy_initialization(self):
        harness = StrategyTestHarness(MyStrategy)
        assert harness.strategy is not None

    def test_order_creation_on_signal(self):
        harness = StrategyTestHarness(MyStrategy)

        # Simulate market conditions
        harness.process_bar_data(
            create_bar_data(symbol="AAPL", close=Decimal("155.00"))
        )

        # Verify strategy behavior
        assert len(harness.get_orders()) == 1
        assert harness.get_portfolio_value() > Decimal("0")
```

## ๐Ÿ”ง CLI Commands

The Tektii CLI provides commands for the complete development lifecycle:

| Command | Description |
|---------|-------------|
| `tektii new <name>` | Create a new strategy from template |
| `tektii serve` | Run strategy as gRPC service |
| `tektii test` | Run strategy tests |
| `tektii validate` | Validate strategy code |
| `tektii push` | Deploy to Tektii platform |
| `tektii logs` | View strategy logs |
| `tektii status` | Check deployment status |

## ๐Ÿ—๏ธ Project Structure

```
my-strategy/
โ”œโ”€โ”€ strategy.py          # Your strategy implementation
โ”œโ”€โ”€ requirements.txt     # Dependencies
โ”œโ”€โ”€ config.yaml         # Strategy configuration
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ test_strategy.py
โ”‚   โ””โ”€โ”€ fixtures.py
โ”œโ”€โ”€ Dockerfile          # Container configuration
โ””โ”€โ”€ README.md          # Strategy documentation
```

## ๐Ÿค Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

### Development Setup

```bash
# Install development dependencies
make install-dev

# Run linting and formatting
make lint
make format

# Run type checking
make type-check

# Run all checks before committing
make check
```

## ๐Ÿ“„ License

This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.

## ๐Ÿ”— Resources

- [Documentation](https://docs.tektii.com/sdk)
- [API Reference](https://docs.tektii.com/sdk/api)
- [Examples](https://github.com/tektii/tektii-sdk-python/tree/main/examples)
- [Changelog](CHANGELOG.md)
- [Roadmap](https://github.com/tektii/tektii-sdk-python/projects/1)

## ๐Ÿ’ฌ Support

- [GitHub Issues](https://github.com/tektii/tektii-sdk-python/issues)
- [Discord Community](https://discord.gg/tektii)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/tektii)
- Email: support@tektii.com

## ๐Ÿ™ Acknowledgments

Built with โค๏ธ by the Tektii team. Special thanks to all our contributors and the open-source community.

---

**Ready to build your trading strategy?** [Get started with our tutorials โ†’](https://docs.tektii.com/sdk/quickstart)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "tektii",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "Tektii Team <support@tektii.com>",
    "keywords": "trading, algorithmic-trading, algo-trading, quantitative-finance, finance, fintech, strategy, backtesting, grpc, trading-bot, trading-strategies, market-data, portfolio-management",
    "author": null,
    "author_email": "Tektii <support@tektii.com>",
    "download_url": "https://files.pythonhosted.org/packages/54/1c/06c5c5ba1edd4fc5ff645b5ba6fa234b79ce88b113015b127e95e7b6f7c8/tektii-1.1.2.tar.gz",
    "platform": null,
    "description": "# Tektii Python SDK\n\n[![PyPI Version](https://img.shields.io/pypi/v/tektii)](https://pypi.org/project/tektii/)\n[![Python Version](https://img.shields.io/pypi/pyversions/tektii)](https://pypi.org/project/tektii/)\n[![License](https://img.shields.io/pypi/l/tektii)](https://github.com/tektii/tektii-sdk-python/blob/main/LICENSE)\n[![Documentation](https://img.shields.io/badge/docs-latest-blue)](https://docs.tektii.com/sdk)\n[![CI Status](https://img.shields.io/github/actions/workflow/status/tektii/tektii-sdk-python/ci.yml?branch=main)](https://github.com/tektii/tektii-sdk-python/actions)\n[![Coverage](https://img.shields.io/codecov/c/github/tektii/tektii-sdk-python)](https://codecov.io/gh/tektii/tektii-sdk-python)\n\n**Build trading strategies that run anywhere - Write Once. Trade Everywhere.**\n\nThe Tektii Python SDK provides a powerful, type-safe framework for building algorithmic trading strategies. Whether you're backtesting historical data or deploying to production, Tektii's event-driven architecture and comprehensive tooling help you focus on strategy development.\n\n## \ud83d\ude80 Features\n\n- **Event-Driven Architecture** - React to market data and order updates in real-time\n- **Type-Safe Models** - Pydantic-powered models with full type hints and validation\n- **Financial Precision** - Built-in Decimal support for accurate financial calculations\n- **Fluent API** - Intuitive order builder with compile-time safety\n- **Testing Framework** - Comprehensive test harness for strategy development\n- **gRPC Integration** - High-performance communication with the Tektii Engine\n- **Production Ready** - Deploy directly to Tektii's cloud infrastructure\n\n## \ud83d\udce6 Installation\n\n### Requirements\n\n- Python 3.11 or higher\n- pip or poetry\n\n### Install from PyPI\n\n```bash\npip install tektii\n```\n\n### Install for Development\n\n```bash\n# Clone the repository\ngit clone https://github.com/tektii/tektii-sdk-python.git\ncd tektii-sdk-python\n\n# Create virtual environment\npython -m venv .venv\nsource .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\n\n# Install in development mode\nmake setup  # or: pip install -e \".[dev]\"\n```\n\n## \ud83c\udfaf Quick Start\n\n### 1. Create Your First Strategy\n\n```python\nfrom decimal import Decimal\nfrom typing import Optional\n\nfrom tektii.strategy import TektiiStrategy\nfrom tektii.strategy.models import BarData, OrderSide, OrderType, TickData\n\n\nclass MyStrategy(TektiiStrategy):\n    \"\"\"A simple moving average crossover strategy.\"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self.position_size = Decimal(\"100\")\n\n    def on_market_data(\n        self,\n        tick_data: Optional[TickData] = None,\n        bar_data: Optional[BarData] = None\n    ) -> None:\n        \"\"\"React to incoming market data.\"\"\"\n        if bar_data and bar_data.close > Decimal(\"150.00\"):\n            # Create and submit a buy order\n            order = (\n                self.create_order()\n                .symbol(bar_data.symbol)\n                .side(OrderSide.BUY)\n                .quantity(self.position_size)\n                .order_type(OrderType.MARKET)\n                .build()\n            )\n            self.submit_order(order)\n```\n\n### 2. Test Your Strategy\n\n```python\nfrom tektii.testing import StrategyTestHarness\nfrom tektii.testing.fixtures import create_bar_data\n\n\ndef test_my_strategy():\n    # Create test harness\n    harness = StrategyTestHarness(MyStrategy)\n\n    # Send test market data\n    test_bar = create_bar_data(\n        symbol=\"AAPL\",\n        close=Decimal(\"151.00\")  # Above our threshold\n    )\n    harness.process_bar_data(test_bar)\n\n    # Verify order was created\n    orders = harness.get_orders()\n    assert len(orders) == 1\n    assert orders[0].side == OrderSide.BUY\n```\n\n### 3. Run Your Strategy\n\n```bash\n# Create a new strategy from template\ntektii new my-strategy\n\n# Test your strategy\ntektii test\n\n# Run strategy locally\ntektii serve --port 50051\n\n# Deploy to Tektii Cloud\ntektii push\n```\n\n## \ud83d\udcda Documentation\n\n### Strategy Development\n\nYour strategy should inherit from `TektiiStrategy` and implement the event handlers:\n\n```python\nclass TektiiStrategy:\n    def on_initialize(self, config: dict[str, str], symbols: list[str]) -> None:\n        \"\"\"Initialize strategy with configuration.\"\"\"\n\n    def on_market_data(self, tick_data: Optional[TickData], bar_data: Optional[BarData]) -> None:\n        \"\"\"Handle incoming market data.\"\"\"\n\n    def on_order_update(self, order_update: OrderUpdateEvent) -> None:\n        \"\"\"Handle order status updates.\"\"\"\n\n    def on_position_update(self, position_update: PositionUpdateEvent) -> None:\n        \"\"\"Handle position changes.\"\"\"\n\n    def on_account_update(self, account_update: AccountUpdateEvent) -> None:\n        \"\"\"Handle account updates.\"\"\"\n\n    def on_shutdown(self) -> None:\n        \"\"\"Clean up resources.\"\"\"\n```\n\n### Order Management\n\nUse the fluent order builder API for type-safe order creation:\n\n```python\n# Market order\nmarket_order = (\n    self.create_order()\n    .symbol(\"AAPL\")\n    .side(OrderSide.BUY)\n    .quantity(Decimal(\"100\"))\n    .order_type(OrderType.MARKET)\n    .build()\n)\n\n# Limit order with time-in-force\nlimit_order = (\n    self.create_order()\n    .symbol(\"GOOGL\")\n    .side(OrderSide.SELL)\n    .quantity(Decimal(\"50\"))\n    .order_type(OrderType.LIMIT)\n    .limit_price(Decimal(\"2500.00\"))\n    .time_in_force(TimeInForce.GTC)\n    .build()\n)\n\n# Stop-loss order\nstop_order = (\n    self.create_order()\n    .symbol(\"MSFT\")\n    .side(OrderSide.SELL)\n    .quantity(Decimal(\"200\"))\n    .order_type(OrderType.STOP)\n    .stop_price(Decimal(\"380.00\"))\n    .build()\n)\n```\n\n### Error Handling\n\nThe SDK provides specific exceptions for different error scenarios:\n\n```python\nfrom tektii.strategy.models.errors import (\n    InvalidOrderError,\n    ValidationError,\n    BrokerConnectionError,\n)\n\ntry:\n    order = self.create_order().build()  # Missing required fields\nexcept ValidationError as e:\n    self.log_error(f\"Order validation failed: {e}\")\nexcept BrokerConnectionError as e:\n    self.log_error(f\"Broker connection lost: {e}\")\n```\n\n## \ud83e\uddea Testing\n\nThe SDK includes comprehensive testing utilities:\n\n```bash\n# Run all tests\nmake test\n\n# Run specific test file\npytest tests/unit/models/test_orders.py\n\n# Run with coverage\nmake test-coverage\n\n# Run only fast tests\nmake test-fast\n```\n\n### Writing Tests\n\n```python\nimport pytest\nfrom decimal import Decimal\nfrom tektii.testing import StrategyTestHarness\n\n\nclass TestMyStrategy:\n    def test_strategy_initialization(self):\n        harness = StrategyTestHarness(MyStrategy)\n        assert harness.strategy is not None\n\n    def test_order_creation_on_signal(self):\n        harness = StrategyTestHarness(MyStrategy)\n\n        # Simulate market conditions\n        harness.process_bar_data(\n            create_bar_data(symbol=\"AAPL\", close=Decimal(\"155.00\"))\n        )\n\n        # Verify strategy behavior\n        assert len(harness.get_orders()) == 1\n        assert harness.get_portfolio_value() > Decimal(\"0\")\n```\n\n## \ud83d\udd27 CLI Commands\n\nThe Tektii CLI provides commands for the complete development lifecycle:\n\n| Command | Description |\n|---------|-------------|\n| `tektii new <name>` | Create a new strategy from template |\n| `tektii serve` | Run strategy as gRPC service |\n| `tektii test` | Run strategy tests |\n| `tektii validate` | Validate strategy code |\n| `tektii push` | Deploy to Tektii platform |\n| `tektii logs` | View strategy logs |\n| `tektii status` | Check deployment status |\n\n## \ud83c\udfd7\ufe0f Project Structure\n\n```\nmy-strategy/\n\u251c\u2500\u2500 strategy.py          # Your strategy implementation\n\u251c\u2500\u2500 requirements.txt     # Dependencies\n\u251c\u2500\u2500 config.yaml         # Strategy configuration\n\u251c\u2500\u2500 tests/\n\u2502   \u251c\u2500\u2500 test_strategy.py\n\u2502   \u2514\u2500\u2500 fixtures.py\n\u251c\u2500\u2500 Dockerfile          # Container configuration\n\u2514\u2500\u2500 README.md          # Strategy documentation\n```\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n### Development Setup\n\n```bash\n# Install development dependencies\nmake install-dev\n\n# Run linting and formatting\nmake lint\nmake format\n\n# Run type checking\nmake type-check\n\n# Run all checks before committing\nmake check\n```\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\udd17 Resources\n\n- [Documentation](https://docs.tektii.com/sdk)\n- [API Reference](https://docs.tektii.com/sdk/api)\n- [Examples](https://github.com/tektii/tektii-sdk-python/tree/main/examples)\n- [Changelog](CHANGELOG.md)\n- [Roadmap](https://github.com/tektii/tektii-sdk-python/projects/1)\n\n## \ud83d\udcac Support\n\n- [GitHub Issues](https://github.com/tektii/tektii-sdk-python/issues)\n- [Discord Community](https://discord.gg/tektii)\n- [Stack Overflow](https://stackoverflow.com/questions/tagged/tektii)\n- Email: support@tektii.com\n\n## \ud83d\ude4f Acknowledgments\n\nBuilt with \u2764\ufe0f by the Tektii team. Special thanks to all our contributors and the open-source community.\n\n---\n\n**Ready to build your trading strategy?** [Get started with our tutorials \u2192](https://docs.tektii.com/sdk/quickstart)\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Build trading strategies that run anywhere - Write Once. Trade Everywhere.",
    "version": "1.1.2",
    "project_urls": {
        "Changelog": "https://github.com/tektii/tektii-sdk-python/blob/main/CHANGELOG.md",
        "Documentation": "https://docs.tektii.com/sdk",
        "Homepage": "https://tektii.com",
        "Issues": "https://github.com/tektii/tektii-sdk-python/issues",
        "Repository": "https://github.com/tektii/tektii-sdk-python"
    },
    "split_keywords": [
        "trading",
        " algorithmic-trading",
        " algo-trading",
        " quantitative-finance",
        " finance",
        " fintech",
        " strategy",
        " backtesting",
        " grpc",
        " trading-bot",
        " trading-strategies",
        " market-data",
        " portfolio-management"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "415c80c3c0ac7363b704e59c88d3469103fe9daf3ba1955596eb8db6f217c2d1",
                "md5": "765279ac6fcaf94bd8c799eaa45a08c0",
                "sha256": "fda3b860e30b70c948e4ccd0063a15fe9328f90c309d2f71e28644dd534dcafe"
            },
            "downloads": -1,
            "filename": "tektii-1.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "765279ac6fcaf94bd8c799eaa45a08c0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 112273,
            "upload_time": "2025-08-04T10:15:26",
            "upload_time_iso_8601": "2025-08-04T10:15:26.387302Z",
            "url": "https://files.pythonhosted.org/packages/41/5c/80c3c0ac7363b704e59c88d3469103fe9daf3ba1955596eb8db6f217c2d1/tektii-1.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "541c06c5c5ba1edd4fc5ff645b5ba6fa234b79ce88b113015b127e95e7b6f7c8",
                "md5": "bef013b519c51c45380398834fcfa927",
                "sha256": "39967ee80980e62798c7b68e02a04723e25e441c116f72bc46a898fc1cd724c5"
            },
            "downloads": -1,
            "filename": "tektii-1.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "bef013b519c51c45380398834fcfa927",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 152617,
            "upload_time": "2025-08-04T10:15:27",
            "upload_time_iso_8601": "2025-08-04T10:15:27.923256Z",
            "url": "https://files.pythonhosted.org/packages/54/1c/06c5c5ba1edd4fc5ff645b5ba6fa234b79ce88b113015b127e95e7b6f7c8/tektii-1.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-04 10:15:27",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "tektii",
    "github_project": "tektii-sdk-python",
    "github_not_found": true,
    "lcname": "tektii"
}
        
Elapsed time: 0.92347s