Explore more topics
Platform comparison · reviewed October 10, 2026

NexusTrade vs QuantConnect: strategy workflow and engine control

Compare NexusTrade's saved-strategy and AI-agent workflow with QuantConnect's code-driven LEAN engine, local tooling and documented execution models.

As of 2026-10-10

Jump to a section

TL;DR

Choose NexusTrade when you want research to become saved strategy rules you can inspect and revise without maintaining an algorithm. Choose QuantConnect's LEAN when you need custom callbacks, fill models or local engine development. Both offer AI assistance. The proposed GOOG translation changes the original recipe's guards, equality and sizing; its reviewed code has no matched completed backtest, so it establishes no return or speed advantage.

See what the saved Google rules do

NexusTrade library preview showing the actual Google moving-average buy and sell rule cards
Actual Google library rule cards, captured October 10, 2026. Configuration only; no test result.
Step 1 of 2

Open the saved rule cards

Open the Google recipe. Its buy uses available cash; its sell is sized from total portfolio value. Read those units before changing the rules.

Open this exact Google recipe
What you should see

The original buy and sell cards shown here are visible in the linked recipe. They describe a configuration, not an executed test.

Step 2 of 2

Follow one buy or sell decision

The examples below use made-up inputs to explain the saved rules. A moving average is an average price over the stated number of days. The waiting periods also have to pass before a rule requests an order.

Buy example · hypothetical
50-day average $140 ≥ 200-day average $130; last buy 15 days ago → buy with 100% of available cash.
Sell example · hypothetical
50-day average $120 ≤ 200-day average $130; last buy 15 days ago and last sell 4 days ago → sell GOOG worth 100% of portfolio value.
Check before translating
At equal averages, both price checks pass. The recipe has waiting periods and no empty-position buy guard.
What you should see

With the illustrated inputs, the first rule requests a buy and the second requests a sell. These are rule decisions, not recorded fills; the saved sell uses portfolio value rather than only held GOOG.

Choose NexusTrade for inspectable rules; choose LEAN for engine control

NexusTrade is the better starting point when you want to turn a research request into saved rules you can read in the app, revise through Aurora, and manage through portfolio tools. The saved example above shows the actual library cards and their definitions. You do not need to maintain a Python algorithm to inspect or change those rules.

QuantConnect is the stronger fit when your strategy needs custom callbacks, fill or margin models, or a local LEAN development workflow. It also has Mia, an AI assistant, so this is not a choice between AI and no AI. The difference is the strategy artifact you own and how much of the engine you need to control.

What each platform lets you own

Show the table · 4 rows, 3 columns

Scroll sideways to compare all columns. Select a heading to sort.

Inspect generated strategySaved conditions and actions shown as rule cards and JSONPython/C# algorithm source; Mia can assist
Use your existing coding assistantMCP portfolio and research tools; Python/TypeScript SDKsLEAN APIs and local CLI; check chosen client integration
Change engine behaviorUse supported platform indicators, conditions and actionsCustom fill, fee, slippage, margin and execution models
Run locallyHosted portfolio workflowLEAN CLI uses Docker; local platform features require the relevant plan

Optional: compare one proposed translation

Review the proposed translation and prepared draft

Use GOOG, daily bars, $10,000 starting capital and January 1, 2020 through December 31, 2024. Buy with available cash when SMA(50) > SMA(200) and the portfolio holds no GOOG; close the GOOG position when SMA(50) < SMA(200). Do nothing at equality. This is a proposed long-only experiment, not a completed test.

This variant changes the saved recipe. The prepared request uses strict comparisons, an empty-position entry guard and a held-position exit, without waiting periods. Review the candidate before testing; a matched completed run is not supplied.

Step 1 of 1

Preview the changed candidate

Open the prepared draft if you want to compare this variant. Its rules differ from the saved recipe you just inspected.

What you should see

The returned candidate should contain the strict comparisons and holding guard described here. Treat any later test as a separate recorded experiment.

The LEAN Python implementation

Inspect the lean python implementation

In QuantConnect, sign in to Algorithm Lab, open Projects, choose Create New Algorithm and create a Python project. Replace main.py with the code below. It defines the same simplified entry and exit experiment. Compile it, then start a backtest and inspect the orders as well as the chart.

The code uses the documented QCAlgorithm, daily equity subscription, SMA indicators and on_data callback. We have reviewed the source and syntax; we have not executed this algorithm in a QuantConnect account or run matched backtests. Indicator warmup and engine fill defaults still need to be aligned before comparing results.

Python
from AlgorithmImports import *

class GoogleMovingAverageExample(QCAlgorithm):
    def initialize(self):
        self.set_start_date(2020, 1, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(10000)
        self.symbol = self.add_equity("GOOG", Resolution.DAILY).symbol
        self.fast = self.sma(self.symbol, 50, Resolution.DAILY)
        self.slow = self.sma(self.symbol, 200, Resolution.DAILY)
        self.set_warm_up(200, Resolution.DAILY)

    def on_data(self, data: Slice):
        if self.is_warming_up or not self.fast.is_ready or not self.slow.is_ready:
            return
        if not data.contains_key(self.symbol) or data[self.symbol] is None:
            return
        holding = self.portfolio[self.symbol]
        if self.fast.current.value > self.slow.current.value and not holding.invested:
            self.set_holdings(self.symbol, 1.0)
        elif self.fast.current.value < self.slow.current.value and holding.invested:
            self.liquidate(self.symbol)

NexusTrade rules for the same proposed experiment

Inspect nexustrade rules for the same proposed experiment

These two candidate rules are constructed with NexusTrade's owning strategy and indicator factories. They are not the built-in recipe or an executed portfolio. Inspect this configuration alongside the Python example: strict comparisons, a zero-versus-positive holding guard, available-cash entry and current-position exit. The portfolio's backtest dates, starting capital and daily evaluation are separate settings.

JSON
View complete record
[
  {
    "name": "Buy 100% of the available cash in GOOG whenever GOOG's 50-day average price is above its 200-day average price and the portfolio holds no GOOG.",
    "userId": null,
    "active": true,
    "condition": {
      "name": "50 Day GOOG SMA > 200 Day GOOG SMA and Position market value (GOOG) = Constant 0",
      "type": "And",
      "description": "All conditions must be true",
      "example": "If Apple's price is up today but down for the week.",
      "conditions": [
        {
          "lhs": {
            "compound": false,
            "targetAsset": {
              "name": "GOOG",
              "type": "Stock",
              "symbol": "GOOG"
            },
            "targetAssets": [],
            "window": {
              "length": 50,
              "interval": "Day"
            },
            "type": "SimpleMovingAverage",
            "name": "50 Day GOOG SMA"
          },
          "rhs": {
            "compound": false,
            "targetAsset": {
              "name": "GOOG",
              "type": "Stock",
              "symbol": "GOOG"
            },
            "targetAssets": [],
            "window": {
              "length": 200,
              "interval": "Day"
            },
            "type": "SimpleMovingAverage",
            "name": "200 Day GOOG SMA"
          },
          "name": "50 Day GOOG SMA > 200 Day GOOG SMA",
          "comparison": "greaterThan",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        },
        {
          "lhs": {
            "compound": false,
            "targetAssets": [
              {
                "name": "GOOG",
                "type": "Stock",
                "symbol": "GOOG"
              }
            ],
            "type": "PositionValue",
            "name": "Position market value (GOOG)"
          },
          "rhs": {
            "compound": false,
            "targetAssets": [],
            "value": 0,
            "type": "Value",
            "name": "Constant 0"
          },
          "name": "Position market value (GOOG) = Constant 0",
          "comparison": "equal",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        }
      ]
    },
    "action": {
      "type": "Buy",
      "targetAsset": {
        "name": "GOOG",
        "type": "Stock",
        "symbol": "GOOG"
      },
      "amount": {
        "type": "percent of buying power",
        "amount": 100
      }
    },
    "orderExecution": {
      "type": "Market"
    },
    "automaticOrderApproval": false
  },
  {
    "name": "Sell 100% of the current GOOG position whenever GOOG's 50-day average price is below its 200-day average price and the portfolio holds GOOG.",
    "userId": null,
    "active": true,
    "condition": {
      "name": "50 Day GOOG SMA < 200 Day GOOG SMA and Position market value (GOOG) > Constant 0",
      "type": "And",
      "description": "All conditions must be true",
      "example": "If Apple's price is up today but down for the week.",
      "conditions": [
        {
          "lhs": {
            "compound": false,
            "targetAsset": {
              "name": "GOOG",
              "type": "Stock",
              "symbol": "GOOG"
            },
            "targetAssets": [],
            "window": {
              "length": 50,
              "interval": "Day"
            },
            "type": "SimpleMovingAverage",
            "name": "50 Day GOOG SMA"
          },
          "rhs": {
            "compound": false,
            "targetAsset": {
              "name": "GOOG",
              "type": "Stock",
              "symbol": "GOOG"
            },
            "targetAssets": [],
            "window": {
              "length": 200,
              "interval": "Day"
            },
            "type": "SimpleMovingAverage",
            "name": "200 Day GOOG SMA"
          },
          "name": "50 Day GOOG SMA < 200 Day GOOG SMA",
          "comparison": "lessThan",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        },
        {
          "lhs": {
            "compound": false,
            "targetAssets": [
              {
                "name": "GOOG",
                "type": "Stock",
                "symbol": "GOOG"
              }
            ],
            "type": "PositionValue",
            "name": "Position market value (GOOG)"
          },
          "rhs": {
            "compound": false,
            "targetAssets": [],
            "value": 0,
            "type": "Value",
            "name": "Constant 0"
          },
          "name": "Position market value (GOOG) > Constant 0",
          "comparison": "greaterThan",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        }
      ]
    },
    "action": {
      "type": "Sell",
      "targetAsset": {
        "name": "GOOG",
        "type": "Stock",
        "symbol": "GOOG"
      },
      "amount": {
        "type": "percent of current positions",
        "amount": 100
      }
    },
    "orderExecution": {
      "type": "Market"
    },
    "automaticOrderApproval": false
  }
]

How the proposed variant changes the saved recipe

The saved recipe and proposed variant differ as shown below. Neither implementation has a published result for the proposed experiment.

Show the table · 4 rows, 3 columns

Scroll sideways to compare all columns. Select a heading to sort.

Signal50-day average >= or <= 200-day averageStrict > or <; no action at equality
Repeat entriesCooldown checks; no explicit empty-position guardEnter only when GOOG is not held
Exit sizing100% of portfolio valueClose current GOOG holdings
CooldownLast-buy and last-sell day checksNone

Exact saved-rule definitions and export

Inspect the original saved rules and JSON

The buy rule checks whether the 50-day moving average is at least the 200-day average, with more than 14 days since the last buy and an additional more-than-3-day buy check. The sell rule checks the inverse state, with more than 14 days since the last buy and more than 3 days since the last sell. These are state checks with cooldowns. They do not require a new crossing event.

The JSON below retains the library conditions and actions while omitting editor forms, generated identifiers and timestamps. It is a semantic export for inspection, not a saved customer portfolio.

The buy spends 100% of buying power; the sell uses 100% of portfolio value. Equality meets both moving-average comparisons. There is no explicit zero-position entry guard. Review those details before changing the recipe or translating it to another engine.

  1. Buy 100% of the available cash in GOOG whenever GOOG's 50-day average price is at or above its 200-day average price and days since the last filled buy order of GOOG is above 14 and days since the last filled buy order of GOOG is above 3.

    Buy GOOG 50 Day GOOG SMA ≥ 200 Day GOOG SMA and # of Days Since the Last Filled Buy Order of GOOG > Constant 14 and # of Days Since the Last Filled Buy Order of GOOG > Constant 3

  2. Sell 100% of the portfolio worth of GOOG whenever GOOG's 50-day average price is at or below its 200-day average price and days since the last filled buy order of GOOG is above 14 and days since the last filled sell order of GOOG is above 3.

    Sell 100% GOOG 50 Day GOOG SMA ≤ 200 Day GOOG SMA and # of Days Since the Last Filled Buy Order of GOOG > Constant 14 and # of Days Since the Last Filled Sell Order of GOOG > Constant 3

JSON
View complete record
[
  {
    "name": "Buy 100% of the available cash in GOOG whenever GOOG's 50-day average price is at or above its 200-day average price and days since the last filled buy order of GOOG is above 14 and days since the last filled buy order of GOOG is above 3.",
    "userId": null,
    "active": true,
    "condition": {
      "name": "50 Day GOOG SMA ≥ 200 Day GOOG SMA and # of Days Since the Last Filled Buy Order of GOOG > Constant 14 and # of Days Since the Last Filled Buy Order of GOOG > Constant 3",
      "type": "And",
      "description": "All conditions must be true",
      "example": "If Apple's price is up today but down for the week.",
      "conditions": [
        {
          "lhs": {
            "compound": false,
            "targetAsset": {
              "name": "GOOG",
              "type": "Stock",
              "symbol": "GOOG"
            },
            "targetAssets": [],
            "window": {
              "length": 50,
              "interval": "Day"
            },
            "type": "SimpleMovingAverage",
            "name": "50 Day GOOG SMA"
          },
          "rhs": {
            "compound": false,
            "targetAsset": {
              "name": "GOOG",
              "type": "Stock",
              "symbol": "GOOG"
            },
            "targetAssets": [],
            "window": {
              "length": 200,
              "interval": "Day"
            },
            "type": "SimpleMovingAverage",
            "name": "200 Day GOOG SMA"
          },
          "name": "50 Day GOOG SMA ≥ 200 Day GOOG SMA",
          "comparison": "greaterThanOrEqual",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        },
        {
          "lhs": {
            "compound": false,
            "targetAssets": [
              {
                "name": "GOOG",
                "type": "Stock",
                "symbol": "GOOG"
              }
            ],
            "side": "Buy",
            "type": "DaysSinceOrder",
            "orderStatus": "Filled",
            "name": "# of Days Since the Last Filled Buy Order of GOOG"
          },
          "rhs": {
            "compound": false,
            "targetAssets": [],
            "value": 14,
            "type": "Value",
            "name": "Constant 14"
          },
          "name": "# of Days Since the Last Filled Buy Order of GOOG > Constant 14",
          "comparison": "greaterThan",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        },
        {
          "lhs": {
            "compound": false,
            "targetAssets": [
              {
                "name": "GOOG",
                "type": "Stock",
                "symbol": "GOOG"
              }
            ],
            "side": "Buy",
            "type": "DaysSinceOrder",
            "orderStatus": "Filled",
            "name": "# of Days Since the Last Filled Buy Order of GOOG"
          },
          "rhs": {
            "compound": false,
            "targetAssets": [],
            "value": 3,
            "type": "Value",
            "name": "Constant 3"
          },
          "name": "# of Days Since the Last Filled Buy Order of GOOG > Constant 3",
          "comparison": "greaterThan",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        }
      ]
    },
    "action": {
      "type": "Buy",
      "targetAsset": {
        "name": "GOOG",
        "type": "Stock",
        "symbol": "GOOG"
      },
      "amount": {
        "type": "percent of buying power",
        "amount": 100
      }
    },
    "orderExecution": {
      "type": "Market"
    },
    "automaticOrderApproval": false
  },
  {
    "name": "Sell 100% of the portfolio worth of GOOG whenever GOOG's 50-day average price is at or below its 200-day average price and days since the last filled buy order of GOOG is above 14 and days since the last filled sell order of GOOG is above 3.",
    "userId": null,
    "active": true,
    "condition": {
      "name": "50 Day GOOG SMA ≤ 200 Day GOOG SMA and # of Days Since the Last Filled Buy Order of GOOG > Constant 14 and # of Days Since the Last Filled Sell Order of GOOG > Constant 3",
      "type": "And",
      "description": "All conditions must be true",
      "example": "If Apple's price is up today but down for the week.",
      "conditions": [
        {
          "lhs": {
            "compound": false,
            "targetAsset": {
              "name": "GOOG",
              "type": "Stock",
              "symbol": "GOOG"
            },
            "targetAssets": [],
            "window": {
              "length": 50,
              "interval": "Day"
            },
            "type": "SimpleMovingAverage",
            "name": "50 Day GOOG SMA"
          },
          "rhs": {
            "compound": false,
            "targetAsset": {
              "name": "GOOG",
              "type": "Stock",
              "symbol": "GOOG"
            },
            "targetAssets": [],
            "window": {
              "length": 200,
              "interval": "Day"
            },
            "type": "SimpleMovingAverage",
            "name": "200 Day GOOG SMA"
          },
          "name": "50 Day GOOG SMA ≤ 200 Day GOOG SMA",
          "comparison": "lessThanOrEqual",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        },
        {
          "lhs": {
            "compound": false,
            "targetAssets": [
              {
                "name": "GOOG",
                "type": "Stock",
                "symbol": "GOOG"
              }
            ],
            "side": "Buy",
            "type": "DaysSinceOrder",
            "orderStatus": "Filled",
            "name": "# of Days Since the Last Filled Buy Order of GOOG"
          },
          "rhs": {
            "compound": false,
            "targetAssets": [],
            "value": 14,
            "type": "Value",
            "name": "Constant 14"
          },
          "name": "# of Days Since the Last Filled Buy Order of GOOG > Constant 14",
          "comparison": "greaterThan",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        },
        {
          "lhs": {
            "compound": false,
            "targetAssets": [
              {
                "name": "GOOG",
                "type": "Stock",
                "symbol": "GOOG"
              }
            ],
            "side": "Sell",
            "type": "DaysSinceOrder",
            "orderStatus": "Filled",
            "name": "# of Days Since the Last Filled Sell Order of GOOG"
          },
          "rhs": {
            "compound": false,
            "targetAssets": [],
            "value": 3,
            "type": "Value",
            "name": "Constant 3"
          },
          "name": "# of Days Since the Last Filled Sell Order of GOOG > Constant 3",
          "comparison": "greaterThan",
          "type": "Base",
          "description": "Left-Hand indicator (comparator) Right-Hand Indicator",
          "example": "If the Rate of Change of Apple's price is > the Value 0."
        }
      ]
    },
    "action": {
      "type": "Sell",
      "targetAsset": {
        "name": "GOOG",
        "type": "Stock",
        "symbol": "GOOG"
      },
      "amount": {
        "type": "percent of portfolio",
        "amount": 100
      }
    },
    "orderExecution": {
      "type": "Market"
    },
    "automaticOrderApproval": false
  }
]

Cost, data and live-account checks

QuantConnect lists a free plan with unlimited backtesting and minute, hourly and daily data. Tick and second data, local VS Code/CLI features and paper/live workflows have different plan requirements. Compute nodes and data subscriptions can add charges. The pricing page does not provide a single price that covers every research and live setup.

NexusTrade subscription and research usage depend on the selected plan and workload. Read the current plan and any job estimate before submitting a run. For either platform, check the required instrument, history, data entitlement and brokerage account separately. A supported broker name does not establish that a particular account has options or margin approval.

Before interpreting a result

Check that both implementations use the same adjusted price history, warmup, evaluation timing and fill convention. Compare the first entry and exit orders. A daily signal can submit an order at a different time than the bar used to calculate it. Align fees, slippage and buying-power assumptions before interpreting return differences.

If there are no trades, inspect indicator readiness and holding guards before changing thresholds. Preserve the original configuration and failed-run details. Only a matched, completed run can support a claim about speed or performance; this page does not supply one.

Continue exploring

Discussion

Sign in or create a free account to join the discussion.

No comments yet.

Aurora · AI research assistant

Try this in Aurora

Edit the request, then open it in Aurora. You choose when to send it.