Live Trading

Commands

Introduction

Commands enable you to manually call methods in your live algorithm as it runs. You can command live projects to update your algorithm state, place orders, or run any other logic. Commands are different from notifications because notifications enable you to send information out of your algorithm while commands enable you to send information into your algorithm.

Basic Usage

To receive and handle generic commands in your algorithm, define the on_commandOnCommand method. This method receives the data you want to inject into your algorithm and returns a boolean that represents if the command was successful.

public class BasicCommandAlgorithm : QCAlgorithm
{

    public override void Initialize() 
    {
        SetBenchmark(x => 1); // So the algorithm needs no asset data.
    }

    public override bool? OnCommand(dynamic data)
    {
        Log($"Got command at {Time} with data: {data}");
        return true;
    }
}
class BasicCommandAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_benchmark(lambda x: 1) # So the algorithm needs no asset data.

    def on_command(self, data):
        self.log(f'Got command at {self.time} with data: {data}')
        return True

To invoke the on_commandOnCommand event handler, send a payload (for example, {"ticker": "AAPL", "quantity": 1}) through the QuantConnect REST API or LEAN CLI. The keys of the payload become the members of the data object.

Encapsulate Event Handlers

To encapsulate the command handler logic, define isolated classes. Command classes should extend the Command class. Extensions of the Command class must implement a runRun method, which receives the payload you send and returns a boolean that represents if the command was successful. To add the command to your algorithm, call the add_commandAddCommand method.

public class EncapsulatedCommandAlgorithm : QCAlgorithm
{

    public override void Initialize()
    {
        AddCommand<MyCommand>();
        SetBenchmark(x => 1); // So the algorithm doesn’t need asset data.
    }

    public void DoSomething()
    {
        Log("Something was done!");
    }
}

public class MyCommand : Command
{
    public string Ticker { get; set; }
    public int Quantity { get; set; }
    public Dictionary<string, string> Parameters { get; set; }
    public override bool? Run(IAlgorithm algorithm)
    {
        ((QCAlgorithm)algorithm).Log($"ticker: {Ticker}; quantity: {Quantity}; parameters: {Parameters}");
        ((EncapsulatedCommandAlgorithm)algorithm).DoSomething();
        return true;
    }
}
class EncapsulatedCommandAlgorithm(QCAlgorithm):

    def initialize(self):
        MyCommand.ALGORITHM = self
        self.add_command(MyCommand)
        self.set_benchmark(lambda x: 1) # So the algorithm doesn’t need asset data.

    def do_something(self):
        self.log('Something was done!')

class MyCommand(Command):
    ALGORITHM = None
    ticker = None
    quantity = None
    parameters = {}

    def run(self, algorithm):
	    if not MyCommand.ALGORITHM:
            algorithm.log('Please set the static reference to the ALGORITHM attribute in the initialize method: `MyCommand.ALGORITHM = self`')
            return False
        algorithm.log(f"ticker: {self.ticker}; quantity: {self.quantity}; parameters: {self.parameters}")
        MyCommand.ALGORITHM.do_something()
        return True

To invoke the runRun method of the class you define, send a payload with a $type key (for example, {"ticker": "AAPL", "quantity": 1, "$type": "MyCommand"}). The value of the $type key must be the Command class you define. The other keys of the payload set the members of the class. If you don’t provide a $type key, LEAN runs the on_commandOnCommand method instead of the runRun method in your custom Command class.

To access your algorithm's attributes, you need to create a global static variable, and assign the reference to the global variable in the algorithm's initialize. Then, in the run merhod, you can acess your algorithm's attributes through the global.

Send Command Link

You can create the command in your algorithm and then send yourself an email notification with a link inside it. When you click the link, it then executes the event handler in your algorithm. To create the link, call the linkLink method. The following algorithm demonstrates how send command requests for the on_command event handler:

public class BasicLinkedCommandAlgorithm : QCAlgorithm
{
    public override void Initialize() 
    {
        SetBenchmark(x => 1); // So the algorithm needs no asset data.
        var link = Link(new {Ticker = "AAPL", Quantity = 1});
        Notify.Email("email@address.com", "Run Command?", $"Click here to run: {link}");
    }

    public override bool? OnCommand(dynamic data)
    {
        Log($"Got command at {Time} with data: {data}");
        return true;
    }
}
class BasicLinkedCommandAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_benchmark(lambda x: 1) # So the algorithm needs no asset data.
        link = self.link({"ticker": "AAPL", "quantity": 1})
        self.notify.email("email@address.com", "Run Command?", f"Click here to run: {link}")

    def on_command(self, data):
        self.log(f'Got command at {self.time} with data: {data}')
        return True

The following algorithm demonstrates how to send command requests for an event handler you encapsulate in a class:

public class EncapsulatedAndLinkedCommandAlgorithm : QCAlgorithm
{
    public override void Initialize()
    {
        AddCommand<MyCommand>();
        SetBenchmark(x => 1); // So the algorithm doesn’t need asset data.
        var potentialCommand = new MyCommand
        {
            Ticker = "AAPL",
            Quantity = 1,
            Parameters = new() { {"tag", "Signal X"} }
        };
        var link = Link(potentialCommand);
        Notify.Email("email@address.com", "Run Command?", $"Click here to run: {link}");
    }

}

public class MyCommand : Command
{
    public string Ticker { get; set; }
    public int Quantity { get; set; }
    public Dictionary<string, string> Parameters { get; set; }
    public override bool? Run(IAlgorithm algorithm)
    {
        ((QCAlgorithm)algorithm).Log($"ticker: {Ticker}; quantity: {Quantity}; parameters: {Parameters}");
        return true;
    }
}
class EncapsulatedAndLinkedCommandAlgorithm(QCAlgorithm):

    def initialize(self):
        self.add_command(MyCommand)
        self.set_benchmark(lambda x: 1) # So the algorithm doesn’t need asset data.
        potential_command = MyCommand()
        potential_command.ticker = 'AAPL'
        potential_command.quantity = 1
        potential_command.parameters = {"tag": "Signal X"}
        link = self.link(potential_command)
        self.notify.email("email@address.com", "Run Command?", f"Click here to run: {link}")

class MyCommand(Command):
    ticker = None
    quantity = None
    parameters = {}

    def run(self, algorithm):
        algorithm.log(f"ticker: {self.ticker}; quantity: {self.quantity}; parameters: {self.parameters}")
        return True

Broadcast Command

You can create the command in your algorithm and then broadcast it to all live algorithms in your organization, except the source algorithm and commands of unregisted type name. The following algorithm demonstrates how broadcast a command to the OnCommandon_command event handler in all your live algorithms:

public class BasicBroadcastCommandAlgorithm : QCAlgorithm
{
    public override void Initialize() 
    {
        SetBenchmark(x => 1); // So the algorithm needs no asset data.
        var broadcastResult = BroadcastCommand(new {Ticker = "AAPL", Quantity = 1});
    }

    public override bool? OnCommand(dynamic data)
    {
        Log($"Got command at {Time} with data: {data}");
        return true;
    }
}
class BasicBroadcastCommandAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_benchmark(lambda x: 1) # So the algorithm needs no asset data.
        link = self.broadcast_command({"ticker": "AAPL", "quantity": 1})

    def on_command(self, data):
        self.log(f'Got command at {self.time} with data: {data}')
        return True

You can control the command data by encapsulating the event handler in a class. The following algorithm demonstrates how to broadcast a command for an event handler you encapsulate in a class:

public class EncapsulatedAndBroadcastCommandAlgorithm : QCAlgorithm
{
    public override void Initialize()
    {
        AddCommand<MyCommand>();
        SetBenchmark(x => 1); // So the algorithm doesn't need asset data.
        var potentialCommand = new MyCommand
        {
            Ticker = "AAPL",
            Quantity = 1,
            Parameters = new() { {"tag", "Signal X"} }
        };
        var broadcastResult = BroadcastCommand(potentialCommand);
    }
}

public class MyCommand : Command
{
    public string Ticker { get; set; }
    public int Quantity { get; set; }
    public Dictionary<string, string> Parameters { get; set; }
    public override bool? Run(IAlgorithm algorithm)
    {
        ((QCAlgorithm)algorithm).Log($"ticker: {Ticker}; quantity: {Quantity}; parameters: {Parameters}");
        return true;
    }
}
class EncapsulatedAndBroadcastCommandAlgorithm(QCAlgorithm):

    def initialize(self):
        self.add_command(MyCommand)
        self.set_benchmark(lambda x: 1) # So the algorithm doesn't need asset data.
        potential_command = MyCommand()
        potential_command.ticker = 'AAPL'
        potential_command.quantity = 1
        potential_command.parameters = {"tag": "Signal X"}
        broadcast_result = self.broadcast_command(potential_command)

class MyCommand(Command):
    ticker = None
    quantity = None
    parameters = {}

    def run(self, algorithm):
        algorithm.log(f"ticker: {self.ticker}; quantity: {self.quantity}; parameters: {self.parameters}")
        return True

Send Commands by API

To send a command to your algorithm, send a payload through the QuantConnect REST API or LEAN CLI. LEAN converts the first character in each key of the payload to uppercase before injecting the data into your algorithm. Follow these steps to send a command from the command line. In this case, the script calls the on_commandOnCommand method.

  1. Create a new console project and change into its directory. Install the requests library, if you haven't already.
  2. dotnet new console -n send_command
    cd send_command
    pip install requests
  3. Save the following code as Program.cssend_command.py.
  4. // Send a command to a live algorithm via the QuantConnect REST API.
    using System.Security.Cryptography;
    using System.Text;
    using System.Text.Json;
    
    // Edit these values:
    var userId = "0";
    var apiToken = "_____";
    var projectId = <project_id>;
    
    var baseUrl = "https://www.quantconnect.com/api/v2/";
    
    Dictionary<string, string> GetHeaders()
    {
        // Get timestamp
        var timestamp = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds().ToString();
        var timeStampedToken = $"{apiToken}:{timestamp}";
    
        // Get hashed API token
        var hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(timeStampedToken));
        var hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
        var authentication = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{userId}:{hash}"));
    
        // Create headers dictionary.
        return new Dictionary<string, string>
        {
            { "Authorization", $"Basic {authentication}" },
            { "Timestamp", timestamp }
        };
    }
    
    async Task<string> CreateCommand(int projectId, object command)
    {
        var client = new HttpClient();
        client.BaseAddress = new Uri(baseUrl);
        foreach (var header in GetHeaders())
        {
            client.DefaultRequestHeaders.Add(header.Key, header.Value);
        }
        // Force camelCase so the body keys stay lowercase even if the variables get renamed.
        var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
        var payload = JsonSerializer.Serialize(new { projectId, command }, options);
        var request = new StringContent(payload, Encoding.UTF8, "application/json");
        var response = await client.PostAsync("live/commands/create", request);
        return await response.Content.ReadAsStringAsync();
    }
    
    // Read the ticker, quantity, and (optional) command type from the command line:
    var ticker = args[0];
    var quantity = int.Parse(args[1]);
    var command = new Dictionary<string, object>
    {
        { "ticker", ticker },
        { "quantity", quantity }
    };
    if (args.Length > 2)
    {
        command["$type"] = args[2];
    }
    Console.WriteLine(await CreateCommand(projectId, command));
    from base64 import b64encode
    from hashlib import sha256
    from time import time
    from sys import argv
    from requests import post
    
    # Edit these values:
    USER_ID = 0
    API_TOKEN = '_____'
    PROJECT_ID = <project_id>
    
    BASE_URL = 'https://www.quantconnect.com/api/v2/'
    
    def get_headers():
        # Get timestamp
        timestamp = f'{int(time())}'
        time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
    
        # Get hased API token
        hashed_token = sha256(time_stamped_token).hexdigest()
        authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
        authentication = b64encode(authentication).decode('ascii')
    
        # Create headers dictionary.
        return {
            'Authorization': f'Basic {authentication}',
            'Timestamp': timestamp
        }
    
    def create_command(project_id, command):
        return post(
            f'{BASE_URL}/live/commands/create',
            headers=get_headers(),
            json={"projectId": project_id, "command": command}
        ).json()
    
    # Read the ticker, quantity, and (optional) command type from the command line:
    ticker = argv[1]
    quantity = int(argv[2])
    command = {'ticker': ticker, 'quantity': quantity}
    if len(argv) > 3:
        command['$type'] = argv[3]
    print(create_command(PROJECT_ID, command))
  5. Replace the placeholder values at the top of the file with your user Id, API token, and project Id.
  6. Run the script, passing the ticker and quantity as arguments. The first form below calls the on_commandOnCommand method; the second adds an optional third argument that sets the $type key to route to an encapsulated Command subclass handler.
  7. dotnet run -- AAPL 1
    dotnet run -- AAPL 1 MyCommand
    python send_command.py AAPL 1
    python send_command.py AAPL 1 MyCommand

To get your user Id and API token, see Request API Token.

Broadcast Commands by API

To broadcast a command to your live algorithms, send a payload through the QuantConnect REST API or LEAN CLI. LEAN converts the first character in each key of the payload to uppercase before injecting the data into your algorithm. Follow these steps to broadcast a command to all projects in your organization from the command line.

  1. Create a new console project and change into its directory. Install the requests library, if you haven't already.
  2. dotnet new console -n broadcast_command
    cd broadcast_command
    pip install requests
  3. Save the following code as Program.csbroadcast_command.py.
  4. // Broadcast a command to all live algorithms in your organization via the QuantConnect REST API.
    using System.Security.Cryptography;
    using System.Text;
    using System.Text.Json;
    
    // Edit these values:
    var userId = "0";
    var apiToken = "_____";
    var organizationId = "_____";
    
    var baseUrl = "https://www.quantconnect.com/api/v2/";
    
    Dictionary<string, string> GetHeaders()
    {
        // Get timestamp
        var timestamp = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds().ToString();
        var timeStampedToken = $"{apiToken}:{timestamp}";
    
        // Get hashed API token
        var hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(timeStampedToken));
        var hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
        var authentication = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{userId}:{hash}"));
    
        // Create headers dictionary.
        return new Dictionary<string, string>
        {
            { "Authorization", $"Basic {authentication}" },
            { "Timestamp", timestamp }
        };
    }
    
    async Task<string> BroadcastCommand(object command)
    {
        var client = new HttpClient();
        client.BaseAddress = new Uri(baseUrl);
        foreach (var header in GetHeaders())
        {
            client.DefaultRequestHeaders.Add(header.Key, header.Value);
        }
        // Force camelCase so the body keys stay lowercase even if the variables get renamed.
        var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
        var payload = JsonSerializer.Serialize(new { organizationId, command }, options);
        var request = new StringContent(payload, Encoding.UTF8, "application/json");
        var response = await client.PostAsync("live/commands/broadcast", request);
        return await response.Content.ReadAsStringAsync();
    }
    
    // Read the ticker, quantity, and (optional) command type from the command line:
    var ticker = args[0];
    var quantity = int.Parse(args[1]);
    var command = new Dictionary<string, object>
    {
        { "ticker", ticker },
        { "quantity", quantity }
    };
    if (args.Length > 2)
    {
        command["$type"] = args[2];
    }
    Console.WriteLine(await BroadcastCommand(command));
    from base64 import b64encode
    from hashlib import sha256
    from time import time
    from sys import argv
    from requests import post
    
    # Edit these values:
    USER_ID = 0
    API_TOKEN = '_____'
    ORGANIZATION_ID = '_____'
    
    BASE_URL = 'https://www.quantconnect.com/api/v2/'
    
    def get_headers():
        # Get timestamp
        timestamp = f'{int(time())}'
        time_stamped_token = f'{API_TOKEN}:{timestamp}'.encode('utf-8')
    
        # Get hased API token
        hashed_token = sha256(time_stamped_token).hexdigest()
        authentication = f'{USER_ID}:{hashed_token}'.encode('utf-8')
        authentication = b64encode(authentication).decode('ascii')
    
        # Create headers dictionary.
        return {
            'Authorization': f'Basic {authentication}',
            'Timestamp': timestamp
        }
    
    def broadcast_command(command):
        return post(
            f'{BASE_URL}/live/commands/broadcast',
            headers=get_headers(),
            json={"organizationId": ORGANIZATION_ID, "command": command}
        ).json()
    
    # Read the ticker, quantity, and (optional) command type from the command line:
    ticker = argv[1]
    quantity = int(argv[2])
    command = {'ticker': ticker, 'quantity': quantity}
    if len(argv) > 3:
        command['$type'] = argv[3]
    print(broadcast_command(command))
  5. Replace the placeholder values at the top of the file with your user Id, API token, and organization Id.
  6. Run the script, passing the ticker and quantity as arguments. The first form below calls the on_commandOnCommand method; the second adds an optional third argument that sets the $type key to route to an encapsulated Command subclass handler.
  7. dotnet run -- AAPL 1
    dotnet run -- AAPL 1 MyCommand
    python broadcast_command.py AAPL 1
    python broadcast_command.py AAPL 1 MyCommand

To get your user Id, API token, and organization Id, see Request API Token and Get Organization Id.

Examples

The following examples demonstrate common practices for implementing live commands.

Example 1: Grey Box

The following algorithm trades a simple EMA cross strategy on SPY. However, instead of direct ordering by the algorithm as a "black box", it sends an email to ask for clicking a confirmation link before ordering, making each order decision an informed manual decision. The algorithm is called a "grey box".

public class LiveCommandAlgorithm : QCAlgorithm
{
    private Symbol _spy;
    private ExponentialMovingAverage _ema;

    public override void Initialize()
    {
        SetStartDate(2024, 9, 12);
        SetEndDate(2024, 10, 1);
        SetCash(1000000);

        // Request SPY data to trade.
        _spy = AddEquity("SPY").Symbol;
        // Create an EMA indicator to generate trade signals.
        _ema = EMA(_spy, 20, Resolution.Daily);
        // Warm-up indicator for immediate readiness.
        WarmUpIndicator(_spy, _ema, Resolution.Daily);
    }

    public override void OnData(Slice slice)
    {
        if (slice.Bars.TryGetValue(_spy, out var bar) && LiveMode)
        {
            // Trend-following strategy using price and EMA.
            // If the price is above EMA, SPY is in an uptrend, and we buy it.
            // We sent a link to our email address and await confirmation.
            string link;
            if (bar.Close > _ema && !Portfolio[_spy].IsLong)
            {
                link = Link(new {Ticker = "SPY", Size = 1});
                Notify.Email("email@address.com", "Trade Confirmation Needed", $"Click here to run: {link}");
            }
            else if (bar.Close < _ema && !Portfolio[_spy].IsShort)
            {
                link = Link(new {Ticker = "SPY", Size = -1});
                Notify.Email("email@address.com", "Trade Confirmation Needed", $"Click here to run: {link}");
            }
        }
    }

    public override bool? OnCommand(dynamic data)
    {
        // If we click the email link to confirm the trade, the algorithm will place the order.
        SetHoldings(data.Ticker, data.Size);
        return true;
    }
}
class LiveCommandAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 12)
        self.set_end_date(2024, 10, 1)
        self.set_cash(1000000)

        # Request SPY data to trade.
        self.spy = self.add_equity("SPY").symbol
        # Create an EMA indicator to generate trade signals.
        self._ema = self.ema(self.spy, 20, Resolution.DAILY)
        # Warm-up indicator for immediate readiness.
        self.warm_up_indicator(self.spy, self._ema, Resolution.DAILY)

    def on_data(self, slice: Slice) -> None:
        bar = slice.bars.get(self.spy)
        if bar and self.live_mode:
            # Trend-following strategy using price and EMA.
            # If the price is above EMA, SPY is in an uptrend, and we buy it.
            # We sent a link to our email address and await confirmation.
            if bar.close > self._ema.current.value and not self.portfolio[self.spy].is_long:
                link = self.link({"ticker": "SPY", "size": 1})
                self.notify.email("email@address.com", "Trade Confirmation Needed", f"Click here to run: {link}")
            elif bar.close < self._ema.current.value and not self.portfolio[self.spy].is_short:
                link = self.link({"ticker": "SPY", "size": -1})
                self.notify.email("email@address.com", "Trade Confirmation Needed", f"Click here to run: {link}")

    def on_command(self, data: DynamicData) -> Optional[bool]:
        # The algorithm will place the order if we click the email link to confirm the trade.
        self.set_holdings(data["ticker"], data["size"])
        return True

Example 2: Parent-Child Communication

Parent algorithm

The parent algorithm is connected to a brokerage. It receives commands from other algorithms and places market orders based on those commands.

public class ParentAlgorithm : QCAlgorithm
{
    public override void Initialize()
    {
        SetStartDate(2024, 9, 1);
        SetEndDate(2024, 12, 31);
        SetCash(100000);
        
        // Remove benchmark so doesn't need asset data.
        SetBenchmark(x => 1);

        // Seed each asset with it's price to trade right away.
        Settings.SeedInitialPrices = true;
    }

    public override bool? OnCommand(dynamic payload)
    {
        Log($"{Time} - Execute on_command(): {payload}");
        var equity = AddEquity(payload.ticker);

        if (!string.IsNullOrWhiteSpace(payload.email))
        {
            Notify.Email(address: payload.email, subject: $"Order Executed from {payload.source}", message: $"{equity.symbol}, {payload.quantity}, {payload.source}");
        }

        MarketOrder(equity.symbol, payload.quantity, asynchronous: true, tag: payload.source);
        return true;
    }
}
class ParentAlgorithm(QCAlgorithm): 

    def initialize(self):
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(100_000)

        # Remove benchmark so doesn't need asset data.
        self.set_benchmark(lambda x: 1)

        # Seed each asset with it's price to trade right away.
        self.settings.seed_initial_prices = True

    def on_command(self, payload):
        self.log(f'{self.time} - Execute on_command(): {payload}')
        equity = self.add_equity(payload.ticker)

        if payload.email:
            self.notify.email(address=payload.email, subject=f"Order Executed from {payload.source}", message=f"{equity.symbol}, {payload.quantity}, {payload.source}")
        
        self.market_order(equity.symbol, payload.quantity, asynchronous=True, tag=payload.source)
        return True
Child algorithm

The child algorithm is connected to a paper trading account. It contains the trading logic and sends commands to the parent algorithm for execution.

public class ChildAlgorithm : QCAlgorithm
{
    // Set the initials to identify the sender and the cash this algorithm will use.
    private const string _initials = "C1";

    public override void Initialize()
    {
        SetStartDate(2024, 9, 1);
        SetEndDate(2024, 12, 31);
        SetCash(100000);
    }

    public override void OnOrderEvent(OrderEvent orderEvent)
    {   
        // When an order is filled, we send a command to the parent algorithm with the order details.
        if (orderEvent.Status == OrderStatus.Filled)
        {
            Log($"{Time} - Sending command");
            var response = Send(orderEvent.Symbol.Value, orderEvent.FillQuantity, _initials);
            Log($"{Time} - Command response {response}");
        }   
    }

    private string Send(string ticker, decimal quantity, string name)
    {
        if (!LiveMode) return string.Empty;
    
        // Set the project ID with the ID of your parent algorithm.
        ProjectId = 30123456;
        // Generate the command link with the desired data payload, and execute with download_data.
        var link = Link(new {ticker, quantity, name});
        return link.DownloadData();
    }
}
class ChildAlgorithm (QCAlgorithm):
    def initialize(self):
        # Set the initials to identify the sender and the cash this algorithm will use.
        self._initials = 'C1'
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(10_000)

    def on_order_event(self, order_event: OrderEvent):
        # When an order is filled, we send a command to the parent algorithm with the order details.
        if order_event.status == OrderStatus.FILLED:
            self.log(f'{self.time} - Sending command')
            response = send(self, order_event.symbol.value, order_event.fill_quantity, self._initials)
            self.log(f'{self.time} - Command response {response}')

def send(algorithm, ticker, quantity, name):
    if not algorithm.live_mode:
        return ''
    # Set the project ID with the ID of your parent algorithm.
    algorithm.project_id = 30123456
    # Generate the command link with the desired data payload, and execute with download_data.
    link = algorithm.link({'ticker': ticker, 'quantity': quantity, 'name': name})
    return Extensions.download_data(link)

Other Examples

For more examples, see the following algorithms:

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: