Explore more topics
NexusTrade guide

Create an algorithmic cryptocurrency strategy

Turn a crypto trading idea into explicit pair, indicator, allocation and exit rules.

As of 2026-10-10

Jump to a section

TL;DR

Define the crypto pair, entry, allocation and exit explicitly. The saved BTC spot example enters with 95% of buying power when price exceeds its 50-day average and no BTC is held, then requests a full exit at or below the average. Inspect the actual signal and fill records, including fees and remaining holdings. Keep a changed allocation in a separate candidate and freeze the chosen rules before testing unexamined dates.

Start with the actual saved BTC trend rule

  1. Entry

    Price > SMA(50, Day) AND position value = 0

  2. Exit

    Price <= SMA(50, Day) AND position value > 0

  3. Allocation

    95% of buying power per entry; sell 100% of held units on exit

  4. Pair

    BTC-USD

  5. Execution

    Market; fractional units enabled

  6. Starting capital

    $10,000; no additional deposits

Show the table · 6 rows, 2 columns
DecisionSaved rule
EntryPrice > SMA(50, Day) AND position value = 0
ExitPrice <= SMA(50, Day) AND position value > 0
Allocation95% of buying power per entry; sell 100% of held units on exit
PairBTC-USD
ExecutionMarket; fractional units enabled
Starting capital$10,000; no additional deposits

This example trades BTC-USD as a spot Cryptocurrency asset. The saved rules were read back and verified with automated trading off.

Watch a recorded entry satisfy both checks

Animation: a BTC trend strategy's entry rule is an AND of two conditions, BTC price above its 50-day SMA and BTC position value equal to 0. A simulated clock runs from Sep 20 to Oct 11, 2024 over the BTC price and the strategy's BTC position value. The position check stays false while the strategy still holds BTC, including after it sells 0.1684 BTC on Oct 2, and turns true when the last 0.0012 BTC is sold on Oct 10. At 13:30 UTC on Oct 11, price 61,420.71 is above the recorded 50-day SMA of 60,767.41, both conditions light true, and the action buys 0.1642 BTC with 95% of buying power at $61,420.71.
The position check stayed false until the last 0.0012 BTC was sold on Oct 10, and on Oct 11, 2024 both checks were true and the bot bought BTC at $61,420.71.
Show the table · 2 rows, 5 columns

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

BTC-USD price > BTC-USD 50 day SMA61,420.7109>60,767.4145True
BTC-USD position value = constant0=0True

At 2024-10-11T13:30:00.000Z, the recorded rule was: BTC-USD last price > 50 Day BTC-USD SMA and Position market value (BTC-USD) = Constant 0. Its overall result was true. Read the individual comparisons below, then ask Aurora to explain how they led to the action.

The signal requested 95 percent of buying power at a submitted price of 61,420.7109. 1 captured Filled order shares this timestamp; Aurora receives those fields with the signal.

Define the trading rule

Choose the full pair and Cryptocurrency asset type. The BTC trend example buys when BTC-USD price is above its 50-day average and no BTC position is held. It allocates 95% of buying power and sells all held units when price is at or below the average. Fractional units are enabled.

Build with Aurora

Use the prepared request in the walkthrough above. Compare the returned saved rules with this guide’s exact entry, exit and sizing before planning a test.

Prompt
Create an undeployed research draft named BTC trend with $10,000 initial value, crypto support and fractional units enabled. Use BTC-USD as Cryptocurrency in every indicator and action. Buy 95% of buying power when Price(BTC-USD) > SMA(BTC-USD,50,Day) AND PositionValue(BTC-USD)=0. Sell 100% of current BTC-USD positions when Price <= SMA50 AND PositionValue > 0. Use Market execution and cash dividends. Review the draft, correct any validation issues, save it and show its exact saved rules and identifier. Keep automated trading off. Stop after saving.

Plan a separate variant and later test

Review the optional next experiment

Keep one changed variant separate from the original. After the development comparison, freeze a chosen version before selecting a later period that has not influenced its rules.

  1. Create one variant, then test unseen dates

    Ask: "Change only the entry allocation from 95% to 75% of buying power. Show the rule diff and compare both candidates on the 2024 development period with every other setting fixed." After choosing, freeze the rules and select another test period you have not inspected. The displayed 2024 results already make 2024 a viewed development period. Keep any later revisions in a new research cycle.

Create and backtest with Python

Use the Python SDK route

Python SDK 1.42.0. Save the runner below as run_btc_trend_following.py.

Install and download

Shell
python3 -m pip install nexustrade==1.42.0
export NEXUSTRADE_API_KEY="YOUR_API_KEY"
curl --fail --output btc_trend_following.py https://nexustrade.io/seo/strategy-examples/btc-trend-following.py

Create, test and inspect

Python
from btc_trend_following import create_btc_trend_following, backtest_btc_trend_following

book = create_btc_trend_following()
completed = backtest_btc_trend_following()
print(completed["result"])

Run

Shell
python3 run_btc_trend_following.py

Python strategy and backtest functions

View complete Python SDK functions

The backtest function submits the 2024 test with SPY as its benchmark, records events and waits for the result. Use a new request key when changing rules, dates or fees.

Python
import nexustrade as nt


def create_btc_trend_following():
    asset = nt.crypto_asset("BTC-USD")
    return nt.portfolio(
        "Public SEO crypto example - BTC 50-day trend",
        [
            nt.strategy(
                "Enter BTC 50-day trend",
                ((nt.Price(asset) > nt.SMA(asset, 50, "Day")) & (nt.PositionValue(asset) == nt.Value(0))),
                nt.buy(asset, 95, "percent of buying power")
            ),
            nt.strategy(
                "Exit BTC 50-day trend",
                ((nt.Price(asset) <= nt.SMA(asset, 50, "Day")) & (nt.PositionValue(asset) > nt.Value(0))),
                nt.sell(asset, 100, "percent of current positions")
            ),
        ],
        initial_value=10000,
        supports_crypto=True,
        supports_fractional_shares=True,
        alerts_enabled=False,
        dividend_policy='cash',
    )


def backtest_btc_trend_following(client=None):
    client = client or nt.NexusTradeClient.from_environment()
    operation = client.create_backtest(
        nt.backtest(
            create_btc_trend_following(),
            start_date="2024-01-01", end_date="2024-12-31",
            interval="Day", baseline_symbol="SPY",
            initial_value=10000, generate_events=True,
            dividend_policy="cash",
            fee_config={"Stock": {"type": "percent", "amount": 0.1},
                        "Cryptocurrency": {"type": "percent", "amount": 0.7},
                        "Option": {"type": "dollars", "amount": 0.65}},
        ),
        idempotency_key="explore-btc-trend-following-2024-spy-v1",
    )
    return client.wait_for_backtest(operation["id"])


# Build locally: book = create_btc_trend_following()
# Run and inspect: completed = backtest_btc_trend_following(); print(completed["result"])

Create and backtest with TypeScript

Use the TypeScript SDK route

TypeScript SDK 1.42.0. Save the runner below as run-btc-trend-following.ts.

Install and download

Shell
npm install nexustrade@1.42.0
npm install --save-dev tsx
export NEXUSTRADE_API_KEY="YOUR_API_KEY"
curl --fail --output btc-trend-following.ts https://nexustrade.io/seo/strategy-examples/btc-trend-following.ts

Create, test and inspect

TypeScript
import { createBtcTrendFollowing, backtestBtcTrendFollowing } from "./btc-trend-following";

async function main() {
  const book = createBtcTrendFollowing();
  const completed = await backtestBtcTrendFollowing();
  console.log(completed.result);
}

main().catch((error: unknown) => {
  console.error(error);
  process.exitCode = 1;
});

Run

Shell
npx tsx run-btc-trend-following.ts

TypeScript strategy and backtest functions

View complete TypeScript SDK functions

The same rules, dates and fees are used in both SDKs. The backtest function keeps its request key across retries.

TypeScript
import * as nt from "nexustrade";

export function createBtcTrendFollowing() {
  const asset = nt.cryptoAsset("BTC-USD");
  return nt.portfolio(
    "Public SEO crypto example - BTC 50-day trend",
    [
      nt.strategy(
          "Enter BTC 50-day trend",
          nt.and(
              nt.gt(nt.Price(asset), nt.SMA(asset, 50, "Day")),
              nt.eq(nt.PositionValue(asset), nt.Value(0))
          ),
          nt.buy(asset, 95, "percent of buying power")
      ),
      nt.strategy(
          "Exit BTC 50-day trend",
          nt.and(
              nt.lte(nt.Price(asset), nt.SMA(asset, 50, "Day")),
              nt.gt(nt.PositionValue(asset), nt.Value(0))
          ),
          nt.sell(asset, 100, "percent of current positions")
      ),
    ],
    { initialValue: 10000, supportsCrypto: true, supportsFractionalShares: true, alertsEnabled: false, dividendPolicy: "cash" }
  );
}

export async function backtestBtcTrendFollowing(client = new nt.NexusTradeClient()) {
  const operation = await client.createBacktest(
    nt.backtest(createBtcTrendFollowing(), {
      startDate: "2024-01-01", endDate: "2024-12-31",
      interval: "Day", baselineSymbol: "SPY",
      initialValue: 10000, generateEvents: true,
      dividendPolicy: "cash",
      feeConfig: {
        Stock: { type: "percent", amount: 0.1 },
        Cryptocurrency: { type: "percent", amount: 0.7 },
        Option: { type: "dollars", amount: 0.65 },
      },
    }),
    { idempotencyKey: "explore-btc-trend-following-2024-spy-v1" }
  );
  if (typeof operation.id !== "string") throw new Error("Missing backtest ID");
  return client.waitForBacktest(operation.id);
}

// Build locally: const book = createBtcTrendFollowing();
// Run and inspect: const completed = await backtestBtcTrendFollowing(); console.log(completed.result);

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.