BTS News

BTS Edge API Code Sample


Click Here to contact us.

BTS Edge API beta helps customers extend their trading platform. This sample demonstrates how easy and intuitive it is to integrate your proprietary algos with our tasking system.

In this example we connect to the EngineService to demonstrate basic interaction with the BTS Edge system. We check that the eye is actively working and set up a heartbeat so the engine can verify that your extension is running correctly. We get and set the parameters for the eye, and define the target securities for the engine.

You can view the complete example on GitHub with comments in the code, or see highlights below.

To Start we create a subscriber to receive eyeinputstate callbacks. The eyeinputstate is the electronic eye-side representation of the securities the eye has been assigned.

_disposables.Add(
_engine_service.subscribe_eyeinputstate().table().Subscribe(table => {
    var original_fg = Console.ForegroundColor;
    Console.ForegroundColor = ConsoleColor.DarkGray;
    Console.WriteLine($"Eye Input - {DateTime.Now.ToString(_TIME_FORMAT_STRING)}");
    Console.WriteLine("Complete State: \n\t" + string.Join("\n\t", table.state.Values));
    Console.WriteLine(new string('=', 80));
    Console.ForegroundColor = original_fg;
}));

Now we create a subscriber to receive eyeoutputstate callbacks. The eyeoutputstate is the electronic eye-side representation of the securities the eye is actively working.

_disposables.Add(
_engine_service.subscribe_eyeoutputstate().table().Subscribe(table => {
    var original_fg = Console.ForegroundColor;
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine($"Eye Output - {DateTime.Now.ToString(_TIME_FORMAT_STRING)}");
    Console.WriteLine("Complete State: \n\t" + string.Join("\n\t", table.state.Values));
    Console.WriteLine(new string('=', 80));
    Console.ForegroundColor = original_fg;
}));

We spawn a hearbeat publisher on a separate thread. The client must provide a heartbeat to the service in order to turn and keep the engine on. If the engine fails to receive a hearbeat within a specified threshold, the engine will turn off.

_heartbeat_thread = new Thread(new ThreadStart(heartbeat));
_heartbeat_thread.Name = "heartbeat";
_heartbeat_thread.Start();
private void heartbeat() {
    EngineService hb_engine_service = _context.locate();
    while (_heartbeat_thread_should_be_alive) {
    hb_engine_service.ping(new EnginePingRequest());
    Thread.Sleep(500);
    }
}

Retrieve the current eye params, change the FillPerSymbol, Threshold amount, and send the new params to the engine.

EyeParameters eye_params = _get_engine_parameters();
eye_params.FillsPerSymbol.ThresholdAmount = 50;
_set_engine_parameters(eye_params);

The sleeps are in place so that you can see changes when the code runs interactively; breakpoints can instead be used when stepping through in the debugger.

Thread.Sleep(1000);

_add_securities_sizes_edges_to_engine(new List() {
_create_security_target_request(654, true, 0.1, 10)
});

_turn_engine_on();

Thread.Sleep(1000);

_turn_engine_off();

Thread.Sleep(1000);

_add_securities_sizes_edges_to_engine(new List() {
_create_security_target_request(654, true, 0.2, 20),
_create_security_target_request(654, false, 0.05, 5),
_create_security_target_request(655, true, 0.01, 1),
_create_security_target_request(655, false, 0.03, 3),
});

_turn_engine_on();

Thread.Sleep(1000);

_turn_engine_off();

_remove_securities_sizes_edge_from_engine(654, true);

while (true) {
Thread.Sleep(1000);
}

get_engine_parameters and set_engine_parameters allow you to get and set the eye parameters.

private EyeParameters _get_engine_parameters() {
    var response = _engine_service.get_eye_parameters(new EyeParametersRequest());
    Console.WriteLine(string.Format("Parameter retrieval successful: {0}", response.Success));
    var p = response.Parameters;
    Console.WriteLine(string.Format($"Underlier Gap \t\t Enabled: {p.UnderlierGap.ThresholdEnabled} \t\t Threshold: {p.UnderlierGap.ThresholdAmount}"));
    Console.WriteLine(string.Format($"Theo Gap \t\t Enabled: {p.TheoGap.ThresholdEnabled} \t\t Threshold: {p.TheoGap.ThresholdAmount}"));
    Console.WriteLine(string.Format($"Hearbeat Gap \t\t Enabled: {p.MissedHeartbeats.ThresholdEnabled} \t Threshold: {p.MissedHeartbeats.ThresholdAmount}"));
    Console.WriteLine(string.Format($"Security fills \t\t Enabled: {p.FillsPerSecurity.ThresholdEnabled} \t\t Amount: {p.FillsPerSecurity.ThresholdAmount} \t Period: {p.FillsPerSecurity.ThresholdPeriod}"));
    Console.WriteLine(string.Format($"Expiration fills \t Enabled: {p.FillsPerExpiration.ThresholdEnabled} \t\t Amount: {p.FillsPerExpiration.ThresholdAmount} \t Period: {p.FillsPerExpiration.ThresholdPeriod}"));
    Console.WriteLine(string.Format($"Symbol fills \t\t Enabled: {p.FillsPerSymbol.ThresholdEnabled} \t\t Amount: {p.FillsPerSymbol.ThresholdAmount} \t Period: {p.FillsPerSymbol.ThresholdPeriod}"));
    Console.WriteLine(string.Format($"ALL fills \t\t Enabled: {p.FillsPerAllfills.ThresholdEnabled} \t\t Amount: {p.FillsPerAllfills.ThresholdAmount} \t Period: {p.FillsPerAllfills.ThresholdPeriod}"));
    return p;
}
private void _set_engine_parameters(EyeParameters p) {
    var response = _engine_service.set_eye_parameters(p);
    string message = (response.Success) ?
    "Parameter set successful!" :
    string.Format("Parameter set error: {0}", response.ErrorMessage);
    Console.WriteLine(message);
}

_create_security_target_request is a helper method that creates new SecurityTargets. A SecurityTarget defines what the engine should look for in terms of a SecurityKey, a security side (IsBuy), edge and size.

private EngineSecurityTargetRequest _create_security_target_request(
        uint security_key, bool is_buy, double edge, uint size) {
    return new EngineSecurityTargetRequest() {
    SecurityKey = security_key,
    IsBuy = is_buy,
    Edge = edge,
    Size = size
    };
}

We add our input SecurityTargets to the collection of our request. Call the service endpoint to add the collection of instruments, sizes and edges to the engine.

private void _add_securities_sizes_edges_to_engine(List input_items) {       
    EngineSecurityTargetCollectionRequest input = new EngineSecurityTargetCollectionRequest();
    input.SecurityTargets.AddRange(input_items);

    _engine_service.add_security_targets(input);
}

We create a new EngineSecurityTargetRequest and set the SecurityKey and IsBuy (side); edge and size are not necessary for removal.

private void _remove_securities_sizes_edge_from_engine(uint security_key, bool is_buy) {
    _engine_service.remove_security_target(new EngineSecurityTargetRequest() {
    SecurityKey = security_key,
    IsBuy = is_buy
    });
}

The Engine can be turned on or off.

_engine_service.turn_on(new EyeSwitchRequest());
_engine_service.turn_off(new EyeSwitchRequest());

Let BTS Edge API’s user-friendly interface, enhanced capabilities and real time functionality reduce your development time and cost. If you are interested in becoming a beta customer, please call or email us to learn more about this opportunity. Or watch us on GitHub to see new samples first.

Have a Question?

Headquarters

194 Finley Golf Course Road
Suite 100
Chapel Hill, NC 27517
Telephone: (919) 913-0850

Support

141 West Jackson
Suite 3732
Chicago, IL 60604
Telephone: (919) 913-0860