This slowness was actually causing us to take too long to complete the
FIX connection logon process, resulting in a timeout and failure to
establish the session. It took almost 1ms per log line, with
logs commonly having 20K lines. k
This is needed at the ICE where some messages can have new lines. We
use the new line separator to separate FIX messages so the parser was
getting confused when it saw multi-line messages.
This is needed at the ICE where some messages can have new lines. We
use the new line separator to separate FIX messages so the parser was
getting confused when it saw multi-line messages.
guard against UI setting cash and leverage factors for accounts I don't know about when span is off
Approved-by: Pedro Pinto <pedro.pinto+atlassian@bluetradesys.com>
This allows IB to remain agnostic of wheter the child cancel was a
simply a consequence of the IB itself shutting down, in which case it
would be ignored. If the IB instead errorred out than that error
superseeds the cancel and results in the IB reporting an error.
Any CPU the algo order receives must originate from a top level event,
its simpler to consolidate all report guards in those events, instead
of chasing every call that comes out of the algo.
[RTM] SP-68 Fix crash on exit by not touching queue on windows. insert_or_replace() is a no-op on windows anyway.
Approved-by: Pedro Pinto <pedro.pinto+atlassian@bluetradesys.com>
RTM - display tooltip again when re-entering same cell where tooltip was previouly closed
Approved-by: Pedro Pinto <pedro.pinto+atlassian@bluetradesys.com>
RTM SP-78 In miniob settings changing the column width directly through the grid (i.e. not through the dialog) has no effect beyond the current popup.
Approved-by: Jake Norbut <jake.norbut@bluetradesys.com>
Approved-by: Pedro Pinto <pedro.pinto+atlassian@bluetradesys.com>
mini-ob - delaying popup Child control creation until approparite button is actually clicked
Approved-by: Pedro Pinto <pedro.pinto+atlassian@bluetradesys.com>
This implements the server side only, the UI does not expose this
configuration so effectively the behaviour right now is
hard-coded until we get around to adding the UI.
We target [.NET Standard 2.0](https://docs.microsoft.com/en-us/dotnet/standard/net-standard) so you can use .NET Framework 4.6.1+ or .NET Core 2.0+. Simply add a reference to the [Spark Nuget package](https://nuget.org) to get started.
```
dotnet new console -lang c#
dotnet add package spark_sdk
dotnet build
```
# C++
The easiest way to get started with C++ is to use the Spark Server SDK to develop your application. Follow the instructions to [download and install the Spark Server SDK](/server/getting-started/install) and open the client_sdk sample project. If you want to run your C++ Client SDK application on Windows [contact us](mailto://api@bluetradesys.com) to get the required headers and binaries.
# JavaScript
We use JavaScript internally with the Spark Client API over a websocket connection but the documentation and packaging isn't ready yet. If this is something you're interested in get in touch with us at [api@bluetradesys.com](mailto:api@bluetradesys.com).
The Spark Client SDK is a high level command and control API which can be used to build scripts or integrate Spark into your existing ecosystem. The API is divided into several independent **"services"** responsible for different aspects of the system. A Service can define both [remote procedure call (RPC)](/client/getting-started/services#rpc) and incremental [streaming](/client/getting-started/services#streams) data.
The [Spark Desktop](https://www.bluetradingsystems.com/bts-spark/) is built on top of this API so you can be assured that it is complete and well tested.
Spark uses [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) as an interface definition language similar to [GRPC](https://grpc.io) but backed by our custom high-performance TCP protocol. We currently support C#/.NET and C++ <!--and Javascript--> but the architecture is designed for easy extension so contact us about your specific business needs.
## Orders
Use the [OrderService](/client/services/orderservice) to send and manage orders including native exchange orders, spreader orders, and custom Algo orders created using the [Spark Server SDK](https://api.bluetradesys.com/server/).
## Spreader
Use the [SyntheticSecurityService](/client/services/syntheticsecurityservice) to create and manage synthetic spreads. Once created these spreads show up in the security and market data feeds just like exchange listed spreads.
## Position
Use the [PositionService](/client/services/positionservice) to get your position and P&L reports or add fills manually to keep the Spark system up to date with an external system.
## Administration
Use the [AdminService](/client/services/adminservice) to manage users and control limits.
## Market Data
For .NET subscribe to market data though the high level MarketDataClient interface. From C++ or JavaScript use the MarketDataRelay service directly.
The Spark Client SDK uses [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) to define the interface for each service in a language independent manner. Services have both functions which return a single result and streams of data which return values continuously while subscribed. This page describes the mapping from the Protocol Buffer definition to the concrete definition in each supported language.
# ServiceContext
To connect your client to the Spark Server you need to get or create a `ServiceContext` instance. A `ServiceContext` represents a connection to the Spark Server and a background thread for handling messages on that connection. Generally there should be a single `ServiceContext` per process. All of the methods on the `ServiceContext` are safe thread safe.
Construct a ServiceContext by calling the default constructor. The ServiceContext will find the Spark Server by loading the server configuration over an HTTP connection. To determine the URL it will search the following locations and use the first one that is present.
* A command line argument `-configserver <url>`
* An environment variable `BTSCONFIG`
*`%APPDATA%/bts/conf/spark.conf` (Windows)
* /sparkdata/conf/spark.conf (Linux)
* $HOME/sparkdata/conf/spark.conf (Linux)
If your application is running on a system with the BTS Client installed this will probably work without any further configuration. If you plan to run your client application on a separate machine we recommend setting the `BTSCONFIG` environment variable.
If you are using the Spark Server SDK to run a local copy of the Spark server set <p><strong>BTSCONFIG = http://localhost:9000/config/</strong></p>
</div>
To get a proxy for a given service call ServiceContext.locate<T>("qualifier") where T is the type of the service and "qualifier" is an optional qualifier used to disambiguate between 2 instances of the same service. The locate call cannot fail but it may return a disconnected proxy. When you make a call on the proxy you should check the call result to see if the method call succeeded.
# RPC
Here is the OrderService reduced to a single method definition. A RPC method always takes exactly 1 argument and returns 1 value. In this example the `create_order` call takes a `Create` instance and returns a `Response`.
```C
serviceOrderService{
rpccreate_order(Create)returns(Response);
...
}
```
The `Create` and `Response` types are also defined as protocol buffer messages. Each field can either be a primitive type another message or a list or map.
```C
messageCreate{
OrderDefinitionnew_order=1;
doubleprice=2;
uint32quantity=3;
}
messageResponse{
uint32order_key=1;
OrderErrorerror_code=2;
stringmsg=3;
}
```
Each RPC call generates both synchronous (blocking) and asynchronous variants. In C# the asynchronous calls have the `_async` suffix and return a `Task`. In C++ the call is overloaded to either return a value synchronously or accept a callback function to be called on the ServiceContext thread when the call completes. <!-- In Javascript only async methods returning a Promise are generated because it never makes sense to make a blocking call in the browser. -->
To call the resulting service locate a proxy using the [ServiceContext](#servicecontext) and then call `cancel_order` or `cancel_order_async`. If you are calling the Spark API from a GUI application you should always prefer the `_async` version of the calls.
Streams allow you to subscribe to live updating data. Each stream represents a changing collection of protocol buffer objects. Similar to a database row each item has an `id` which uniquely identifies it within the collection. Updates from the Spark server can add, remove or replace entries in the collection. Since only the changed items are sent over the wire the stream can remain responsive even when it represents a large collection.
Streams are implemented using the language bindings for [ReativeX](http://reactivex.io/) which provide utility functions to drill down to the specific data your application needs. In C# we provide both mutable and immutable versions of the generated data types (C++ users can rely on `const`).
When defined in a proto file streams use the `stream` keyword on the result type.
```C
service OrderService {
...
rpc fills (FillsSub) returns (stream Fill);
}
```
### C# example
```c#
var sc = new ServiceContext();
var orders = sc.locate<OrderService>();
var fills_observable = orders.subscribei_fills();
var unsub = fills_observable.Subscribe(update => {
In this section we're going to use the Remote - Containers feature of <a href="https://code.visualstudio.com/" target="_blank">Visual Studio Code<i class="fa fa-fw fa-window-restore" aria-hidden="true"></i></a> to simplify the development experience. If you are using a different editor skip to the <a href="#other-editors">other editor</a> section below.
## Remote - Containers
The Visual Studio Code Remote containers extension allows it to run a complete development environment inside the Spark SDK Docker container. The editor UI runs as a thin client on your desktop and connects to a headless instance running inside the Spark SDK Docker environment. This configuration allows us to ship a pre-configured set of [Tasks](https://code.visualstudio.com/Docs/editor/tasks) for building and testing your code.
Start Visual Studio Code and click on the puzzle piece icon on the left-hand side to open the extensions panel. Use the search box at the top to find the "Remote - Containers" extension and install it.
Open the examples/algo_template directory using the File->Open Folder menu option. If you opted to add it to your path during install, you could run `code .` from your command prompt.
When the workspace opens, you should see a notification offering to let you re-open the workspace inside the container.
The first time you open the workspace inside the container it will take a few seconds to configure the spark_sdk docker container. While the workspace is open in Visual Studio Code the docker image will also be running in the background. The container will stop automatically when you close the editor.
Open algo_template.cpp from the file browser on the left or by pressing ctrl-p and typing the name. Each Algo is a standard C++ class which implements **IAlgoOrder**. Placing your cursor on IAlgoOrder and pressing F12 will take you to the IAlgoOrder.h header file where you can browse the API. To learn more about how an Algo is instantiated see the [Algo Initialization](/server/ref/initialization).
## Compiling
To build press "Ctrl+Shift+B". You should see the build output at the bottom of your screen. If the build was successful the resulting algo_template.so will be automatically copied to the plugins directory where it will be loaded by the Spark server process on start.
<img src="../compiled.png" width="640" />
## Debugging
To debug your Algo set a breakpoint (F9) and open the Debug panel (Ctrl+Shift+D) and choose "(gdb) Launch". This will launch the Spark Server inside the container with the debugger attached.
<img src="../gdb_launch.png" width="380" />
With sparkd running you can launch the Spark Client (spark_client.cmd) and it will connect to the running server. Log in with the user "bts" and no password and open a ladder. You can now select your Algo on the order type dropdown and activate it by clicking on a price on the ladder.
<img src="../myalgo.png" width="150" />
While sparkd is running you can also access the Spark Server Admin interface on [http://localhost:9000](http://localhost:9000). Use the same "bts" login to access the admin interface. Here you can manage user and account permissions and risk limits.
## Starting Spark Server
To start the Spark Server without attaching a debugger press "Ctrl+Shift+P" and select "Tasks: Run Task" and then "Start Sparkd" and "Never scan task output" This will open a new terminal where you can see any messages logged with the **Sdk** subsystem as well as any warnings or errors. To stop the Spark server simply kill the terminal (trash can icon) or run the "Stop Sparkd" task.
## Next Steps
If you would like to understand more about how Docker is working behind the scenes continue to the [next section](#other-editors). Otherwise, continue to [Algo Registration](/server/ref/registration) to learn how Algos are registered with the Spark.
<hr>
# Other Editors
In this section you will be more exposed to the details of how Docker works and how to compile and test your Algo using the command line.
## Docker
Spark Server is built and runs only on Linux so you need a Linux development environment to effectively develop plug-ins for it. Docker lets you take the spark_sdk.img disk image and run it inside a virtual Linux machine running on your Windows desktop.
First, some terminology. A Docker "image" is a disk image containing a complete filesystem. The spark_sdk.img file you imported earlier is an image. A Docker "container" is what you get when you get when you attach this image to a running Linux system. You can connect to a running container and use it to run commands like the C++ compiler or the Spark server. Directories from your local filesystem can be mapped into the Docker container when it starts so you can easily share files.
### Start
The first step is to start the spark_sdk Docker container with the examples directory mapped so we can compile the examples inside the container. In your command prompt cd to the *examples* directory that you unzipped from the spark_sdk.zip file. Then run the following command to start the container.
The container will remain as long as this prompt is open. You can attach an additional to the running container with the following command:
{% clipable() %}
docker exec -it spark_sdk bash
{% end %}
## Compiling
Let's look at the algo_template sample first. All of the samples are laid out similarly with a `build.sh` script for compiling. As long as you are running build.sh inside the spark Docker container, it automatically copies the build output to /sparkbin/plugins/ where it needs to be to get loaded by the Spark server.
```
bts@spark_sdk:/examples$ cd algo_template/
bts@spark_sdk:/examples/algo_template$ ./build.sh
algo_template.so copied to /sparkbin/plugins/
Restart sparkd to see changes.
```
## Starting Spark Server
To start the Spark server `cd /sparkbin/` and run `./sparkd run`. Press Ctrl+C to stop it.
You will see any Sdk log messages as well as any log messages at or above Warning level from other parts of the system. If you need additional diagnostic information more details logs are stored in /sparkdata/data/logging/log. These logs will be automatically deleted when you stop the Docker container.
With sparkd running you can launch the Spark Client (spark_client.cmd) and it will connect to the running server. Log in with the user "bts" and no password and open a ladder. You can now select your Algo on the order type dropdown and activate it by clicking on a price on the ladder.
<img src="../myalgo.png" width="150" />
While sparkd is running you can also access the Spark Server Admin interface on [http://localhost:9000](http://localhost:9000). Use the same "bts" login to access the admin interface. Here you can manage user and account permissions and risk limits.
## Debugging
You can debug your algo using gdb from the bash command prompt.
```bts@spark_sdk:/sparkbin$ gdb --args ./sparkd run
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
...
Reading symbols from ./sparkd...done.
(gdb) break algo_template.cpp:45
No source file named algo_template.cpp.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (algo_template.cpp:45) pending.
(gdb) run
Starting program: /sparkbin/sparkd run
```
If your editor supports debugging over the ssh protocol you can start sshd from inside the container.
## Next
Continue to [Algo Registration](/server/ref/registration) to learn how Algos are registered with the Spark.
To start using the Server SDK you will need to request access though our sales department. Please email <a href="mailto:api@bluetradesys.com">api@bluetradesys.com</a> or call <a href="tel:919-913-0850">(919) 913-0850</a> and we will provide download credentials.
## Download
Download the latest SDK image here: [spark_sdk.zip](https://api.bluetradesys.com/download/spark_sdk.zip)
Unzip that folder into a working directory. Inside you should see something like this:
```
spark_sdk.img
client/
spark_client.cmd
examples/
```
## Import
Import the spark_sdk image into docker using the `docker load` command.
<strong>If you see this error it means Docker Desktop is not running:</strong>
error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.40/images/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.
</div>
Confirm that the import worked by running `docker images` which should list the new image.
```
c:\bts> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bluetradingsystems/spark_sdk latest e2be89436e73 4 hours ago 3.89GB
If you are using Linux or Mac replace <strong>%CD%</strong> with <strong>$PWD</strong>.
</div>
The first time you invoke `docker run` you may be prompted to "share" your filesystem with Docker. This usually works fine but if you run into trouble, see <a href="">Docker Desktop for Windows tips</a> on avoiding common problems.
## Success 🎉
Docker is now running the spark SDK image. If you are on Windows or Mac it is running inside a virtual Linux machine. You can see that is is running by typing `docker ps` to list running docker containers. If you restart the Docker Desktop application you will need to start the spark_sdk image again using `docker start spark_sdk`.
You should now be able to access an admin interface at http://localhost:8008/ which will let you stop and start the spark server process.
-->
## Update
To update your Spark SDK simply download an unzip a new [spark_sdk.zip](https://api.bluetradesys.com/download/spark_sdk.zip) and use `docker load < spark_sdk.img` to overwrite the old image with the new one.
To preserve the old image so you can go back to it later run `docker tag spark_sdk spark_sdk:your_custom_tag` before loading the new SDK image.
<!--
Then stop, remove and restart spark_sdk.
```
c:\bts> docker stop spark_sdk
c:\bts> docker rm spark_sdk
c:\bts> docker run -d -v %cd%:/sdk --name spark_sdk bluetradingsytems/spark_sdk
These instructions assume you are using Microsoft Windows but you should be able to follow them on a Linux or Mac with minor modifications.
{% linux() %}
When there is a significant difference on non-Windows platforms it will be called out in a box like this one.
{% end %}
{% info() %}
Tips or solutions to common problems will be highlighted in a box like this.
{% end %}
The minimum hardware requirements for using the SDK are:
- **12 GB** RAM (preferably 16 GB or more)
- 4 CPU cores
- 20 GB free hard disk space
The Spark SDK uses a tool called Docker to distribute all of the tools you need to build and test your trading algorithm ("Algo"). Once you have Docker installed you can download and import the Spark SDK image and be ready to start developing your Algo in a few minutes.
## Docker
Download and install <a href="https://www.docker.com/products/docker-desktop" target="_blank">Docker Desktop for Windows/Mac. <i class="fa fa-fw fa-window-restore" aria-hidden="true"></i></a>
If you are using Linux follow the <a href="https://docs.docker.com/install/#supported-platforms">official install instructions for Docker for your distribution.</a>
</div>
During the install Docker may ask you to enable virtualization support and reboot.
Once Docker Desktop is installed and running it will create an icon in your system tray area that looks like the Docker logo.

Right click on the tray icon and choose 'Settings' and choose the 'Advanced' tab.
Ensure that the docker image has 8192 MB of memory and at least 2 cores. Memory that you assign to the docker image will not be available to Windows/Mac while Docker is running. CPU cores are shared with the host OS. Since you are going to use this image to compile your Algo it makes sense to allow Docker to use all available cores.
<img src="../docker_config.png" width="640" >
## Sharing
You need to give Docker access to the Windows drive where your source code is kept.
Open Settings -> Shared Drives and check the drive where you intend to keep your Algo source code.
If you run into trouble with drive sharing, see <a href="https://code.visualstudio.com/docs/remote/troubleshooting#_docker-desktop-for-windows-tips">Docker Desktop for Windows tips</a> on avoiding common problems.
</div>
## Editor
The Server SDK includes a complete configuration for C++ development with the <a href="https://code.visualstudio.com/" target="_blank">Visual Studio Code <i class="fa fa-fw fa-window-restore" aria-hidden="true"></i></a> editor. If you are a new to C++ development on a Linux system we recommend you give this a try as it's the easiest way to get up and running quickly. Of course, If you have a different editor that you prefer we fully support that as well.
Using the **Spark Server SDK**, users can create new order types ("Algos"). In this case, users implement the new functionality in C++, producing a shared library that is loaded at run time by our Spark Server.
If you are interested in accessing Spark server remotely, please see the [Spark Client SDK](/client/).
## Speed
The Spark platform offers a sub-10 microsecond socket to socket response times for algorithmic trading. With the **Spark Server SDK**, you can create your order types in high-performance C++ and load them into the Spark server.
Since your order is running inside the Spark Server, there is virtually no overhead allowing your algorithm to take full advantage of the speed Spark offers. Hosting a high-performance language like C++ directly in the Spark server process allows it to respond to the market thousands of times faster than an Algo built using a proprietary drag and drop tool.
## Easy to Get Started
If you are not actively developing with C++, it can be time-consuming to set up a complete development environment from scratch. That is why we provide a full development environment out of the box with [Docker](https://docker.io) so you can download and try the Server SDK quickly and easily.
Docker works across Windows, macOS, and Linux, so you don't need to change your development environment to try the Spark API. Docker also ensures that all of the dependencies you need are packaged together in one image, so you know it will work out of the box, no matter the platform.
## Implementation
Creating a new Algo begins with implementing a standard C++ class derived from IAlgoOrder. Start from the [algo_template](/server/samples/template) example to get going quickly.
The first call your new Algo receives is [do_before_launch](/server/ref/initialization#before-launch), which is an opportunity to validate parameters and allocate any long-lived resources needed during execution. Next, it receives either [do_launch](/server/ref/initialization#launch-launch-attached) in the case of a new order or [do_launch_attached](/server/ref/initialization#launch-launch-attached) if the order is attaching to an existing order.
The Algo receives a reference to [IAlgoServices](/server/ref/subscriptions/), which is how it calls out to the Spark system. It will use [IAlgoServices](/server/ref/subscriptions/) to subscribe to market events, launch and control child orders, and communicate its state to the larger Spark system.
## Fully Integrated
When a Spark Server plugin is loaded, it registers its exposed Algos with the Spark Server though the [init_spark_plugin](/server/ref/registration) callback. This callback allows the Algo to describe the parameters it expects so they can be automatically entered in the [Spark Client](https://www.bluetradingsystems.com/bts-spark/).
<img src="../myalgo.png" width="150" />
<img src="../paramsui.png" width="460" />
Compose your Algo with out of the box Algos in the [Spark Algo Studio](https://www.bluetradingsystems.com/news/155-bts-algo-studio-provides-algo-library-with-customization-functionality) to create new functionality on the fly.
## I need to make a call that might take a few seconds. What is the best way to do this?
Create a background thread in [do_before_launch](/server/ref/initialization#before-launch) or [do_launch](/server/ref/initialization#launch-launch-attached) to do the work. Use [on_timer](/server/ref/subscriptions#timer) to poll until the result is available.
## I don't see the header files in the .zip file. Where are they?
The SDK headers are baked into the docker image along with the build tools. Once you've loaded the image with `docker load < spark_sdk.img` you can run this command to copy them out to your local file system `docker run --rm -it -v $PWD:/out spark_sdk /bin/tar -cvf /out/headers.tar /sdk/include` This will copy the headers to the current directory in headers.tar. We still recommend doing the actual build inside the docker environment but having a copy of the headers can be useful for setting up your development environment.
Each Algo derives from IAlgoOrder and overrides virtual methods to receive callbacks from the Spark system.
## Before Launch
When an order is activated by a user or by another Algo, the first call it receives is do_before_launch. This call happens outside of the latency-sensitive path, so it's the place to validate parameters and set up data structures that the Algo might need.
This call returns an OrderOpResult, which allows it to fail and return an error message to its creator. If a user created this order, this message is displayed in the [Activity Log](https://www.bluetradingsystems.com/docs/bts_spark/Help/#activity-log) and across the bottom of the ladder.
Every SDK Algo is a "Dynamic" Algo since it's parameters are defined during [registration](/server/ref/registration/). Use the `get_if<T>` helper to retrieve a named parameter from the `order_params` collection as a `std::option<T>`. If a parameter has a valid default value you can use `std::option::value_or(...)` to set default values for missing parameters. If a parameter *must* exist or must be within a certain valid range, return an error to the caller.
The parameters are defined during <a href="/server/ref/registration/">registration</a> by the <a href="/server/ref/registration/#dynamicorderdescriptor">DynamicOrderDescriptor</a>.
</div>
### IBeforeLaunchAlgoServices
IBeforeLaunchAlgoServices is passed to `do_before_launch` and allows the Algo to query its environment.
Depending on the state of `is_attaching()` the next call will either be `do_launch` or `do_launch_attached`. The only difference is that in `do_launch_attached` the existing OrderKey and ChildState are provided.
`do_launch` and `do_launch_attached` are in the latency-sensitive path and should not do more work than needed. These functions get a reference to `IAlgoServices`, which is a superset of the functionality available on `IBeforeLaunchAlgoServices`. Most Algos should store a pointer or reference to this object for managing child orders (it has a stable address).
Now is the time to use `IAlgoServices` to subscribe to market events that are relevant to your Algo and create any child orders that need to exist at the start of your Algo. You can safely call IAlgoServices from any `IAlgoOrder` callback.
To learn more about subscribing to events see [subscriptions](/server/ref/subscriptions).
### Things to do in the launch callback
☑ Store a reference to IAlgoServices
☑ Subscribe to relevant market events
☑ Launch a child order?
## Update
If the user or parent Algo changes the order parameters (price, size, or the custom parameters defined during registration), Spark calls the `do_update` callback with the new parameters. It is up to the Algo to decide how to apply the new parameters to update the running state. It can do this by canceling, changing, or adding new child orders.
Every Algo must, at some point, launch a child order to be useful. Each child order can be another Algo or regular exchange order. When the child order is updated or filled, those changes are also sent to the parent.
# Templates
Since launching a child order is one of the most latency-sensitive things an Algo can do, the Server SDK enables you to create a child template. An order template prepares an order based on a known OrderDefinition and gets it ready to send on a background thread. When the Algo determines it is time to send the order, it only needs to provide the price and quantity to complete and send the order. If an Algo expects to send multiple child orders, it can reserve more than one. Preparing a child template is typically done in [do_before_launch](http://127.0.0.1:1111/server/ref/initialization/#before-launch) callback.
```cpp
virtualChildTemplate&
IBeforeLaunchAlgoServices::make_child_template(
api::orderman::OrderDefinitionconst&child_def,
size_treserve=1);
```
# Launch
IAlgoServices provides two overloads for launching child orders. By default, launching a child order automatically subscribes the Algo to its state changes.
Launch a child order from a template if you have one prepared. This is the fastest option.
When a child is launched its `OrderKey` is returned to the caller. This ID can be used to update, cancel, or detach the child order.
## Update
To update an existing child order, call update_child and pass an Update. The Update type lets you change the price, size or the entire OrderDefinition. You only need to specify the fields that you intend to update so only set the price() field if that is what you are changing.
To cancel an existing child order call `cancel_child`. When the order is canceled you will receive an update though the `on_child_change` callback.
```cpp
voidIAlgoServices::cancel_child(OrderKeychild);
```
## Detach
The lifetime of a child order is tied to its parent. If a parent is canceled or completed child orders are automatically stopped as well. If the Algo needs to launch an order that will continue after the Algo ends use `detach_child` to sever the connection. This order hierarchy can be viewed in the Spark [Order Book](https://www.bluetradingsystems.com/docs/bts_spark/Trading/#order-book).
```cpp
voidIAlgoServices::detach_child(OrderKeychild);
```
To detach all children at once use `detach_all_children`.
```cpp
voidIAlgoServices::detach_all_children();
```
# Child Updated
When a child order is updated the parent receives the `on_child_change` callback with an updated ChildState object.
When Spark Server starts, it loads all plugins listed in the /sparkbin/plugins directory and calls an exported function named `init_spark_plugin` which must have the following signature.
The `init_spark_plugin` function registers the Algo with a DynamicOrderDescriptor. Once registered, the Algo appears in the [Spark ladder](https://www.bluetradingsystems.com/docs/bts_spark/Trading/#ladder) and the [Algo Studio](https://www.bluetradingsystems.com/docs/bts_spark/Trading/#algo-studio).
To register an Algo call `register_dynamic_algo_order` on the provided bts::SparkServices instance. This function takes the DynamicOrderDescriptor and a function that is called to construct the IAlgoOrder. A single init_spark_plugin can call register_dynamic_algo_order multiple times to register multiple Algos.
The DynamicOrderDescriptor must have a dynamic_order_type (name), or the registration will fail.
```cpp
DynamicOrderDescriptordesc;
desc.set_dynamic_order_type("My Algo");
autoresult=
serv.register_dynamic_algo_order(
desc,[](){returnstd::make_unique<MyAlgo>();});
if(result!=bts::AlgoRegistrationResult::SUCCESS){
// Algo failed to register
}
```
## DynamicOrderDescriptor
The DynamicOrderDescriptor describes the type of parameters that the Algo accepts. These inputs can come either from the user manually entering them or from a parent Algo. Spark Algos are composable, so one Algo can activate another. See [Child Orders](/server/ref/orders) for more on how to activate custom order types as child orders.
Add parameters to the DynamicOrderDescriptor by calling `add_param_desc()` and setting the name and parameter type.
Each descriptor can be one of the following types:
```
// Primitive
int32
uint32
double
string
bool
// Complex
Order
Array
Struct
```
**Currently the Spark UI only renders parameters with primitive types.** The complex types can only be provided by a parent order.
### Order
This parameter type indicates that another order type parameterizes this Algo. When the Algo needs to create a child order, it can use this parameter type to create a custom order type instead of defaulting to a limit order.
For example, an Algo might be designed to wait for a specific market condition before putting in an order. Instead of placing a limit order when the condition is met, the user can specify that it should an IceBerg order. The Algo doesn't need special logic to handle different child order types.
### Array
An array parameter is a collection of the same type of parameter. If your Algo needed to behave differently depending on a table of prices, you could send that list in though an array parameter.
```cpp
*desc.add_param_desc()=
param_array("Price Points",
param_double("unused").param_type());
```
### Struct
A struct parameter is a set of named parameter types similar to the entire DynamicOrderDescriptor. The struct parameter type can be combined with the array type to handle tabular data.
An Algo exists to observe changes in the market and respond to them. When the Algo is [launched](1/server/ref/initialization/#launch-launch-attached) it uses IAlgoServices to subscribe to the events it needs to operate. Each subscribe call is paired with a matching unsubscribe call, which takes the same argument to unsubscribe.
# Book
Subscribe to book updates for the specified security call use subscribe_book and unsubscribe book.
```cpp
// Subscribe to book updates for the specified security
To handle time-based logic, an Algo can subscribe to a common timer event that is invoked once every 10 milliseconds. Use the TimeStamp class from `bts_chrono.h` to efficiently handle time calculations.
```cpp
// Subscribe to a periodic 10ms timer
voidIAlgoServices::subscribe_timer();
// You implement
virtualvoidon_timer()override;
```
# Ticker
The status callback is called when the market for this security opens, closes, or has some other state transition.
When an Algo launches a child order, it is subscribed to the changes on that child automatically. If the Algo unsubscribes from those changes, it can re-subscribe using this method.
```cpp
// Subscribe to child order updates for the specified child order.
Join starts working N ticks away from the market (usually) and then watches for the opposite inside to become same side inside market; if there is then enough size on that market, it will join.
a high-performance professional futures front end, connected via our proprietary protocol over TCP to our Spark Server, which in turn connects to execution venues via their native protocols.
Use the Spark SDK to extend Spark Server with your custom Algos, then use the Client SDK to launch and control them.
</p>
</div>
<divclass="inverted-colours selling-points">
<divclass="selling-points__content container">
<divclass="selling-header">
<imgsrc="/images/API.png"width="100%"/>
</div>
<divclass="selling-point">
<h2>
Server SDK
<iclass="fa fa-tachometer"aria-hidden="true"></i>
</h2>
<p>
Leverage the ultra-low latency Spark C++ API to develop and run your custom Algo. Have your first sub-10 microsecond trading algorithm running in under an hour.
The goal of the lean order is to watch the opposite-inside market size and cross when that size goes below the threshold (this also implies a cross if that size goes to zero and the market trades away from you) If the market trades toward you, you can opt into several different behaviors
##### Parameters
* Cross Thresh - size thresh in absolute or ratio terms
* Max Chase Ticks - max levels to pay up, in ticks
## Join
The goal of the join order is to watch the opposite-inside market and join when the market flips (that is, when the best offer becomes the best bid) and has at least threshold size.
##### Parameters
* Join Thresh - size thresh in absolute or ratio terms
## Top
The goal of the top order is to not trade by yourself, but the intent at the time of order entry is to get filled.If the order is on the market (say current bid price) AND the quantity on that bid price is below top thresh then cancel the order else remain working.
##### Parameters
* Top Thresh - size thresh in absolute or ratio terms
## Cover
A Cover order’s purpose is to fire a hedge order (of any type) in response to fills from it’s child order on the opposite side of the market N ticks away
##### Parameters
* Profit Ticks - ticks above or below fill price to place profit / cover order
## OCO
An OCO order creates a relationship between a child order and a 'stop' or 'other' order such that when one of these is cancelled, both cancel, or when one is filled, the other order's size is debited in the amount of the fill.
Composing this order with Cover simulates scalping functionality
##### Parameters
* Stop Ticks - ticks below or above main order to place stop / other order
The goal of the lean order is to watch the opposite-inside market size and cross when that size goes below the threshold (this also implies a cross if that size goes to zero and the market trades away from you) If the market trades toward you, you can opt into several different behaviors
##### Parameters
* Cross Thresh - size thresh in absolute or ratio terms
* Max Chase Ticks - max levels to pay up, in ticks
## Join
The goal of the join order is to watch the opposite-inside market and join when the market flips (that is, when the best offer becomes the best bid) and has at least threshold size.
##### Parameters
* Join Thresh - size thresh in absolute or ratio terms
## Top
The goal of the top order is to not trade by yourself, but the intent at the time of order entry is to get filled.If the order is on the market (say current bid price) AND the quantity on that bid price is below top thresh then cancel the order else remain working.
##### Parameters
* Top Thresh - size thresh in absolute or ratio terms
## Cover
A Cover order’s purpose is to fire a hedge order (of any type) in response to fills from it’s child order on the opposite side of the market N ticks away
##### Parameters
* Profit Ticks - ticks above or below fill price to place profit / cover order
## OCO
An OCO order creates a relationship between a child order and a 'stop' or 'other' order such that when one of these is cancelled, both cancel, or when one is filled, the other order's size is debited in the amount of the fill.
Composing this order with Cover simulates scalping functionality
##### Parameters
* Stop Ticks - ticks below or above main order to place stop / other order
## Splitter
The splitter is useful for pro-rata markets where you want to vary your exposure independent of the order quantity that you want to fill. The splitter will complete when the number of fills reaches or exceeds the order quantity but it will put exposed_qty total size on the market. Splitter favors order size over queue position.
If exposed_qty is set to 0 the splitter will continue to exist in the Order Book but will cancel all of its child orders. This makes it a useful building block for custom algos that need to implement a 'paused' state.
##### Parameters
* exposed_qty - The total quantity to expose on the market.
* max_order_qty - The maximum size of a single order.
## Scratch
The scratch algo is similar to Lean, but instead of watching the opposite inside market, it watches the same side market and pays up when this quantity recedes below the scratch_threshold
##### Parameters
* scratch_threshold - The quantity on the same side market below which to scratch
* chase_ticks - The number of ticks through the opposite market to pay up
## ProRata
The prorata algo is a special case hedging algo for pro-rata markets. Users can specify two hedge types-- normal hedge and overfill hedge, the latter is spawned when you receive more fills than your fill_limit. Further, the algo attempts to scratch when in an overfilled state AND optionally the same side size falls below stay_in_threshold
##### Parameters
* hedge_ticks - The amount of ticks better hedges are placed on the opposite side market as the fill
* chase_ticks - How many ticks through the opposite market on a scratch
* fill_limit - The limit after which the algo considers further fills to be 'overfills'
* stay_in_threshold - A same side size threshold that enables the algo to 'stay in' even if overfilled
* enable_scratch_on_overfill - When true, overfills are immediately scratched upon the algo exiting
* enable_stay_in - When true, the algo will 'stay in' so long as the same side size is above stay_in_threshold, when false the algo attempts to 'get out' (and potentially scratch overfills) as soon as it reaches overfill status
* hedge - Child order type to send for normal hedges
* overfill_hedge - Child order type to send for overfill hedges
- Fixed a bug where some CME currency spreads exhibited incorrect tick values
## 2.15.2
### User Visible Changes
- Excel RTD plugin can now receive ICE market data
## 2.15.1
### Bug Fixes
- Fixed a FIX log parsing issue that resulted in exchange gateway logon problems
## 2.15.0
### User Visible Changes
- Added ability to hide Ladder status messages via Ladder Settings -> Left Panel tab -> Show/Hide groupbox -> Status Message
- Synthetic cloning now allows for any parameter to be changed, including tick size and leg contracts
- Added ability to import synthetics from a CSV file; see our manual for further details on this process
- Reduced Iceberg reloading latency
### Bug Fixes
- Fixed a bug where highlighted fills could lose their highlight status
- Fixed a bug where the (Mini) OrderBook PIQ could be displaying an old value
## 2.14.3
### Bug Fixes
- Fixed a bug regarding ICE logon messaging
## 2.14.2
### Bug Fixes
- Fixed a bug regarding ICE messaging
## 2.14.1
### Bug Fixes
- Fixed a bug regarding ICE logon authentication
## 2.14.0
### User Visible Changes
- All ladders can now be recentered by (shift or alt) + double clicking over the Price column in a ladder
- Added a Max Order Quantity setting to the Safety Checks tab on the Ladder settings. This setting allows for a user-defined maximum order quantity.
- Added a Price Display Format setting to the Market Price and Size Display tab on the Ladder settings. This setting allows for price levels in the ladder to be displayed without a decimal separator.
- Synthetic instrument creation with 3 legs no longer defaults to butterfly quantites
### Bug Fixes
- Fixed an issue where market transition were not observed by IAlgoOrder
- Fixed a bug in error reporting
- Fixed a bug in the PnL window where specifying a certain grouping order would lead to a UI failure
## 2.13.0
### User Visible Changes
- Added the name of the spreader to the parent algo badge (for spreader child orders), in the fills, orderbook and floating orderbook windows
- Added support for sounds for new orders
- Added a new quoting throttle parameter for the spreader, that throttles quotes that are moving toward the inside market but are still a configurable number of ticks away
- Enabled the ladder to remember the left panel scroll position across front end restarts
### Bug Fixes
- Fixed the local fills window so that it does not show the admin fills
- Removed the deleted accounts from the ladder accounts dropdown
- Fixed the orderbook price for iceberg of spreaders
## 2.12.0
### User Visible Changes
- Added support for ICE market data and order execution
### Internal Changes
- Lots of permission / admin changes to facilitate ICE
## 2.11.0
### User Visible Changes
- Fixed fills form time filter to also apply to SOD fills
- Addressed an issue that could prevent the web Admin UI from displaying over slow HTTP connections
- Removed the option to enter manual spread fills
- Fixed an issue that could cause erroneous fill account attribution in the event of a crash
### Internal Changes
- Added support for tag 1031. Currently defaults to Y, can it be override through config.
- To facilitate support, allowed the bts user to view and edit algos from all other users
- Improved system tests
- Improved log messages in UI to include dispatcher thread name
- Added support for Windows core dumps in the UI
## 2.10.0
### User Visible Changes
- Fills now include information about the algo that originated the fill
- A new, more powerful PnL form is now available
### API Changes
- Added security state information (pre open, halted, normal, closed, etc)
### Bug Fixes
- Brought back the "select all" check box in the mini order book
- Fixed an issue in the market data subsystem that on rare occasions could result in a startup crash
### Internal Changes
- Fixed an issue that was stopping us from interpreting SOD times as local rather than GMT
## 2.9.3
### Internal Changes
- Fixed system test scripts
## 2.9.2
### Bug Fixes
- Fixed an issue with the exchange simulator that could lead to crossed markets
## 2.9.1
### Bug Fixes
- Fixed an issue with trade sound alerts, where in some cases the use of a "In Between" condition could lead to a UI failure.
- Fixed an issue with the display of the new raw position column in the market view window.
- Fixed the popup label that describes the raw position information in the ladder
### Internal Changes
- Avoided shipping production configuration defaults that lead to trying to download a position file for the development sftp server.
### Api
- C# API sample now uses synchronous calls.
## 2.9.0
### User Visible Changes
- Improved Workspace management User Interface
- Added the ability to change grid background colors
- The Spark UI Window group now has a title in the Windows task bar
- Added sound alerts for trade events, see Launcher -> Settings -> Alerts
- Allowed composite algos that are attached to existing orders to identify fills that were already present prior to attachment
- Added import facilities for GMI position files
- Added the ability for risk managers to enter manual fills
- Added "raw" P&L columns, that is columns that *do not* include spread legs in their accounting
### Bug Fixes
- Fixed the settings action menu (Load/Save/Reset to Factory)
- Fixed the method used to determine if a security is expired to take into account the start of day time
### API Changes
- Fixed an issue in the Client SDK that could lead to occasional failures to connect to the spark server as well as excessive memory usage.
- Added the ability for algo orders to distinguish fills existing prior to launch
### Internal Changes
- Changed how we packaged certain third-party components
- Added logging of entitlement status
- Tagged outgoing orders with sequence number of marketdata or FIX event that triggered them
## 2.8.3
### Bug Fixes
- Fixed a bug that could cause an OrderBook's Security column filter to be blank
- Fixed a bug that could cause a UI failure when clearing a filter selection on a filtering widget
## 2.8.2
### Bug Fixes
- Added proper display factors for SOM spreads
- Fixed a bug that could cause a UI failure when trying to change settings in a synthetic ladder
## 2.8.1
### Bug fixes
- Fixed an error in the UI grids filtering widget
## 2.8.0
### User Visible Changes
- Added ProRata and Scratch algos
- Ladder badge now grows/shrinks to fill the containing cell
- Attached algo parameters are now displayed in the update panel
- Fixed a bug where the update panel would show '-' values when only
1 order was selected
- Fixed a bug that cause cause a failure on startup if the user
loaded a workspace with a Ladder that had a dynamic order type
selected by default
- Increased width of login panel to better show login error messages
- Added optional 'Maker/Taker' pricing to Spreader algo
- Algo buttons in ladder can now be made to deactivate after launching an algo or remain 'sticky'
### Internal changes
- Made it easier to generate simple UI's for new order types
### API Changes
- Dynamic orders can now use QuantityMeasure parameter types
## 2.7.2
### User Visible Changes
- Changed the login dialog to avoid leaking workspace names from other users.
- Added new Splitter algo. From the manual: The splitter is useful
for pro-rata markets where you want to vary your exposure
independent of the order quantity that you want to fill. The
splitter will complete when the number of fills reaches or exceeds
the order quantity but it will put exposed_qty total size on the
market. Splitter favors order size over queue position.
### Internal Changes
- Made spark more resilient to lack of connectivity to the CME web site for downloading of templates.
## 2.7.1
### User Visible Changes
- Fixed some issues with the Cover algo, where in some circumstances
it would erroneously cancel launched hedges on completion.
## 2.7.0
### User Visible Changes
- Allowed algos to process "in-flight" fills while shutting down
- Changed the cover algo to continue to hedge while shutting down
### API Changes
- Changed the API so that algos do not fully terminate until all
their children are terminated. Algos that are in the process of
shutting down in response to a complete or cancel call will still
receive child updates, which they can use to calculate and report
an accurate fill count (during this shutdown stage algos cannot
create, cancel or update children). A new IAlgoServices method,
is_shutting_down(), can be used to determine if an algo is
shutting down.
## 2.6.2
### User Visible Changes
- Fixed an issue in the ladder where in some cases the mini order book could not be brought up from a badge
- Fixed a rare race condition that could lead to erroneous limit enforcement
- Fixed an issue with the margin limits where an error could occur if an account name with more than 12 chars was used
## 2.6.1
### User Visible Changes
- Fixed an issue in the ladder where an error could occur when trying to change ladder settings for the first time
## 2.6.0
### User Visible Changes
- In the ladder made last trade more distinctive when overlayed on the volumn column
- In the ladder, corrected display of volume tool tip
- In the ladder, changed the consolidation of last trade to consider only the price ignoring aggressor changes
- Added an option for the Top Algo to delete itself if within N ticks from top of book
- Address a rare issue that could lead to an error report on UI exit
- Added margin risk limits
- Added the "Offset" algo. Offset prices a child algo at a parameterizable distance from the top of the book
- Avoided switching the current account and order type on open ladders when limits are changed
### Internal Changes
- Ensure that admin logins are always allowed to login, regardless of keycode status.
## 2.5.0
### User Visible Changes
- Added loss limit risk check
- Made algos, synthetics and user names private so that multiple users can share a single system privately.
- Allowed the mini order book defaults for column widths to be changed from the mini order book
- Allowed the mini order book to shrink to the minimum size that will be needed to display the selected columns
- Improved accuracy of the directional arrow when displaying last trades in the volumn column
## 2.4.0
### User Visible Settings
- In the ladder, changed the last trade column to accumulate successive trades at the same price
- Fixed a bug in the order book where the right side ladder would display the top leve order's security rather then current row's
- Added OK, Cancel buttons to the security picker for ladder profiles or sounds
- Added ladder settings for the mini order book
- Added a safety check to guard against unintentional market crosses
- Improved the Queue Holder mode in the spreader:
- Added a Show Quantity, allowing the spreader to keep queue position of the trailing orders as Fills (of size Show Qty) happen
- Improved spreader performance when in Queue Holder mode
### Internal changes
- Suppressed order callbacks for completed/canceled orders. This should eliminate some bogus error logs by spreader orders.
- Addressed a potential concurrency issues with service initialization.
## 2.3.0
### User Visible Changes
- Introduced multiple settings profiles for the ladder
- This allows multiple standard configuration for the ladder, optionally with security specific variations
- Made Cover order more independent from its hedging chidren:
- Cover continues to operate even if an hedging child is canceled
- When a cover is canceled it will detach from any running hedging children, instead of canceling them
- Changed Lean, Join and Cover algos to hide themselves in the ladder once they have completed their work
- Changed manual fills to appear in day PnL rather than in the SOD records
- Add buy/sell coloring to fill rows in fills window
- Streamlined the mini order book:
- Display of the mini order book popup is quicker
- Only exchange orders are displayed
- Update buttons are only displayed for orders that are under control of an algo with the update applying to the entire algo, not just the exchange order
- We can now select multiple rows to attach, detach, update or cancel multiple orders in a batch
- A checkbox column has been added to make clearer which rows are selected
### API Changes
- Enhanced the API to allow algos to implement custom cancel handling
- Allowed algos to control their visibility in the ladder through the API
### Internal Changes
- Added system requirements to Spark documentation
- Improved market data diagnostics for bad configurations
- Changed market data default buffer size
## 2.0.3
### Internal changes
- Improved backwards compatibility in UI settings
## 2.0.2
### User Visible Changes
- Middle click the ladder price column to show the orders for that price level
- Middle click the ladder price column to show the orders for that price level
- Middle click the bid or ask column in the ladder no longer sends an order
### Internal changes
@@ -95,8 +346,8 @@ insert_anchor_links = "right"
- Improved settings manager tool output
- Added diagnostics in the event MD memory corruption is detected
- Added systems tests for join,lean, iceberg and spreader orders
- Made exchange order recovery more resilient in the presence of database loss
- Made exchange order recovery more resilient in the presence of database loss
## 1.6.2
### User Visible Changes
### Exchange simulator
@@ -121,7 +372,7 @@ insert_anchor_links = "right"
- Integrated stunnel into UI to make VPN setup unnecessary in unsecured environments.
## 1.5.7
### User Visible Changes
- New videos have been added to the manual describing the [Algo Studio](./bts_spark/Trading/index.md#algo-studio) and [Spreader](./bts_spark/Spreader/index.md)
- New videos have been added to the manual describing the [Algo Studio](./bts_spark/Trading/_index.md#algo-studio) and [Spreader](./bts_spark/Spreader/_index.md)
- Fixed a bug that occasionally would cause windows to be position outside the visible screen on startup
- Fixed a bug in the order book form that would occasionally cause the Recreate Order option to be unavailable
- Added a confirmation step to Cancel All, Cancel Buys and Cancel Sells commands
- Fixed missing securities in the Fills and P&L windows.
@@ -182,7 +433,7 @@ insert_anchor_links = "right"
#### Bug Fixes
- Fixed the "Since Open" time filter to use the exchange open time rather than 8:30 AM
- Fixed a bug in the order book where sometimes parent orders would not update their last message column.
#### Algos
- Added OCO Algo
- An OCO order creates a relationship between a child order and a 'stop' or 'other' order such that when one of these is cancelled, both cancel, or when one is filled, the other order's size is debited in the amount of the fill. Composing this order with Cover simulates scalping functionality
@@ -190,7 +441,7 @@ insert_anchor_links = "right"
- Improved SDK documentation and usability
- Dynamic orders are now properly identified in the order book
#### Documentation
- Information on the Spark API has been added to the Spark manual
- Information on the Spark API has been added to the Spark manual
- The documentation has been updated and reorganized to make information easier to find
### Internal Changes
- Improved robustness of limit system test
@@ -245,6 +496,7 @@ insert_anchor_links = "right"
- The zoom functionality can also be performed via hotkey and mouse wheel combinations
- Zoom In = CTRL + Mouse wheel up
- Zoom Out = CTRL + Mouse wheel down
- Reset zoom = CTRL + Mouse wheel click or double click on the zoom slider
### Exchange simulator
- Improved the exchange simulator to track real market data more closely
@@ -351,6 +603,7 @@ insert_anchor_links = "right"
- All windows now contain a settings page where grid settings (font color, size, etc) are applied
- These settings can be saved on a per-window basis or as a Default for newly-launched windows
_error_reporter.report_error($"Unable to delete synthetic security ({id}): unable to determine whether or not security ({id}) has working orders (deletion is not permitted while there are working orders).");
Log.Ui.warn($"Ignoring request to delete synthetic security ({id}) because the orders lookup timed out (must confirm no working orders).");
M 87.5 10 C 80.313542 10 74.400391 15.913151 74.400391 23.099609 V 397.90039 C 74.400391 405.08685 80.313541 411 87.5 411 h 374.80078 c 7.18646 0 13.09961 -5.91315 13.09961 -13.09961 V 23.099609 C 475.40039 15.913151 469.48724 10 462.30078 10 Z m 13 26.199219 H 449.19922 V 384.90039 H 100.5 Z M 21.099609 76.400391 C 13.912943 76.400391 8 82.313333 8 89.5 v 374.80078 c 0 7.18667 5.912943 13.09961 13.099609 13.09961 H 395.90039 c 7.18667 0 13.09961 -5.91294 13.09961 -13.09961 0 -7.18667 -5.91294 -13.10156 -13.09961 -13.10156 H 34.199219 V 89.5 c 0 -7.186667 -5.912943 -13.099609 -13.09961 -13.099609 z M 274.90039 116.5 c -7.18667 0 -13.09961 5.91294 -13.09961 13.09961 V 197.5 h -67.90039 c -7.18667 0 -13.09961 5.91294 -13.09961 13.09961 0 7.18667 5.91294 13.09961 13.09961 13.09961 h 67.90039 v 67.90039 c 0 7.18667 5.91294 13.09961 13.09961 13.09961 7.18667 0 13.09961 -5.91294 13.09961 -13.09961 v -67.90039 h 67.90039 c 7.18667 0 13.09961 -5.91294 13.09961 -13.09961 v -0.0391 -0.0391 C 368.85982 203.37217 363.03372 197.5 355.90039 197.5 H 288 V 129.59961 C 288 122.41294 282.08706 116.5 274.90039 116.5 Z
</sys:String>
<!--File (the icon is free to use if we include this information in our credit section)
M 22.589844 14.470703 H 0.82421875 C 0.36896661 14.470586 -1.1747368e-4 14.83967 0 15.294922 v 4.669922 c -1.1747368e-4 0.455252 0.36896661 0.824336 0.82421875 0.824218 H 16.940231 l 0.425003 -1.09375 0.554688 -0.554687 H 1.6484375 V 16.119141 H 20.941406 Z M 27.462891 9.5976562 V 8.0742188 A 0.8240064 0.8240064 0 0 0 26.638672 7.25 H 0.82421875 A 0.8240064 0.8240064 0 0 0 0 8.0742188 v 4.6699222 a 0.8240064 0.8240064 0 0 0 0.82421875 0.824218 H 23.492188 l 1.648437 -1.648437 H 1.6484375 V 8.8984375 H 25.814453 V 11.246094 Z M 0.82421878 2.736881e-8 A 0.8240064 0.8240064 0 0 0 2.7433281e-8 0.82421879 V 5.4941406 A 0.8240064 0.8240064 0 0 0 0.82421878 6.3183594 H 26.638672 A 0.8240064 0.8240064 0 0 0 27.46289 5.4941406 V 0.82421879 A 0.8240064 0.8240064 0 0 0 26.638672 2.736881e-8 Z M 1.6484375 1.6484375 H 25.814453 V 4.6699219 H 1.6484375 Z M 31.628051 7.2558423 19.165575 19.718635 23.70324 24.256618 36.166032 11.793823 Z m -0.0013 3.5965607 0.941422 0.94142 -8.866233 8.866232 -0.94142 -0.94142 z m -13.240122 9.708458 -1.636234 6.110706 6.109329 -1.637606 z
Geometry="M 5.3507926 32.045363 H 17.81645 v 2.401501 H 5.3507926 Z m 0 -4.937233 H 24.132995 v 2.401501 H 5.3507926 Z M 18.799228 22.222041 v 2.32929 h -1.567173 v -2.264886 q -2.179014 -0.01073 -4.057475 -0.987533 v -2.973336 q 0.622575 0.504501 1.856993 0.933864 1.234417 0.429362 2.200482 0.493766 v -3.907198 q -2.511771 -0.933863 -3.4349 -2.018003 -0.912395 -1.094874 -0.912395 -2.662047 0 -1.685248 1.191482 -2.8659947 1.19148 -1.1914807 3.155813 -1.3846939 V 4.918734 h 1.567173 v 1.9535992 q 2.264887 0.1073411 3.38123 0.7299162 V 10.500446 Q 20.677689 9.5880506 18.799228 9.3841034 v 4.0682086 q 2.35076 0.847992 3.370495 1.942866 1.019736 1.08414 1.019736 2.629845 0 1.781854 -1.137811 2.876728 -1.13781 1.08414 -3.25242 1.32029 z M 17.232055 12.829737 V 9.4270397 q -1.492034 0.2683516 -1.492034 1.5564393 0 1.105608 1.492034 1.846258 z m 1.567173 3.628113 v 3.25242 q 1.53497 -0.236149 1.53497 -1.53497 0 -1.051939 -1.53497 -1.71745 z m 13.258587 13.65074 h -3.954117 l 0.0014 7.641804 -7.643169 -10e-7 0.0014 3.952751 h 7.640439 l 0.0014 7.641803 h 3.951385 l 0.0014 -7.641802 7.640437 -10e-7 0.0014 -3.952751 -7.643169 10e-7 z M 5.3507926 36.982596 h 5.5381524 v 2.401501 H 5.3507926 Z M 1.3730469 0 A 1.3741374 1.3741374 0 0 0 0 1.3730469 V 45.630859 a 1.3741374 1.3741374 0 0 0 1.3730469 1.373047 H 16.853516 a 17.906029 17.906029 0 0 1 -0.05859 -1.373047 17.906029 17.906029 0 0 1 0.06836 -1.375 H 2.7480469 V 2.7480469 H 33.326172 V 27.783203 a 17.906029 17.906029 0 0 1 1.375 -0.05859 17.906029 17.906029 0 0 1 1.373047 0.06836 V 1.3730469 A 1.3741374 1.3741374 0 0 0 34.701172 0 Z" />
Geometry="m 26.463403 27.963318 h -2.359042 l -0.683586 -2.137882 h -3.417929 l -0.676884 2.137882 h -2.345638 l 3.498351 -9.610414 h 2.566798 z M 22.92484 24.163384 21.89276 20.933106 q -0.113931 -0.361899 -0.160844 -0.864535 h -0.05361 q -0.03351 0.422214 -0.167545 0.837727 l -1.045485 3.257086 z m 2.065112 7.055953 -1.51223 1.51223 2.923087 2.922042 -2.923087 2.923086 1.51223 1.511185 2.922042 -2.922042 2.923086 2.922042 1.511185 -1.511185 -2.922041 -2.923086 2.922041 -2.922042 -1.511185 -1.51223 -2.923086 2.923087 z m -9.484387 0.416058 h 6.108175 v 1.176737 h -6.108175 z m 0 -2.419244 h 9.203284 v 1.176735 h -9.203284 z m 0 4.83849 h 2.713696 v 1.176736 H 15.505565 Z M 13.556469 15.93316 a 0.67332766 0.67332766 0 0 0 -0.672794 0.672793 v 21.686339 a 0.67332766 0.67332766 0 0 0 0.672794 0.672793 h 7.585433 a 8.7739586 8.7739586 0 0 1 -0.02871 -0.672793 8.7739586 8.7739586 0 0 1 0.0335 -0.673751 H 14.230219 V 17.279703 h 14.983289 v 12.267233 a 8.7739586 8.7739586 0 0 1 0.67375 -0.02871 8.7739586 8.7739586 0 0 1 0.672794 0.0335 V 16.605953 A 0.67332766 0.67332766 0 0 0 29.887258 15.93316 Z" />
Geometry="m 24.706673 31.196264 -3.086181 3.086182 5.96548 5.963348 -5.96548 5.96548 3.086181 3.084049 5.963348 -5.963348 5.96548 5.963348 3.084049 -3.084049 -5.963347 -5.96548 5.963347 -5.963348 -3.084049 -3.086182 -5.96548 5.965481 z M 5.3507926 32.045363 H 17.81645 v 2.401501 H 5.3507926 Z m 0 -4.937233 H 24.132994 v 2.401501 H 5.3507926 Z M 26.434166 6.0031559 14.993666 17.443656 9.6399578 12.089946 6.0100982 15.719802 c 2.9622322 2.959826 6.0772448 6.092263 8.9969908 8.970151 L 30.064121 9.6329208 Z M 5.3507926 36.982596 h 5.5381524 v 2.401501 H 5.3507926 Z M 1.3730469 0 A 1.3741374 1.3741374 0 0 0 0 1.3730469 V 45.630859 a 1.3741374 1.3741374 0 0 0 1.3730469 1.373047 H 16.853516 a 17.906029 17.906029 0 0 1 -0.05859 -1.373047 17.906029 17.906029 0 0 1 0.06836 -1.375 H 2.7480469 V 2.7480469 H 33.326172 V 27.783203 a 17.906029 17.906029 0 0 1 1.375 -0.05859 17.906029 17.906029 0 0 1 1.373047 0.06836 V 1.3730469 A 1.3741374 1.3741374 0 0 0 34.701172 0 Z" />
Loaded 100 of 1055 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.