> ## Documentation Index
> Fetch the complete documentation index at: https://docs.liftx.io/llms.txt
> Use this file to discover all available pages before exploring further.

# One-shot Pine example

> A bounded demonstration emitting at most one OPEN and one later termination.

<Warning>
  Public sample only: dummy key, synthetic link/instrument and an intentionally expired credential timestamp. It starts disabled and cannot connect as published. Obtain the fully populated private script from Liftx, and keep it disabled while production execution is unavailable. Never publish the real generated copy.
</Warning>

The One-shot example is intended for a deliberate demo validation after activation. It sends at most one OPEN and one termination, using one immutable lifecycle reference. Its default termination target is **One strategy position**.

## Configure the real generated copy

1. Create a valid setup with OPEN and terminate and an approved small demo quantity.
2. Generate **Pine (advanced) → One-shot · scheduled demo** in Liftx.
3. Set a future **OPEN time** and a **TERMINATE time** at least 60 seconds later, before key expiry.
4. After activation, enable the indicator and create **Any alert() function call** before OPEN time. Keep alert expiration after TERMINATE time and within credential lifetime.
5. Observe both events in the provider log, Liftx Activity and the actual position.

Realtime chart updates drive the schedule. If the first eligible OPEN update is at least 60 seconds late, the helper skips OPEN. Missing updates or delivery can prevent termination. It does not rearm or recover state after restart.

The Data Window phase is local signal state: `0` idle, `1` waiting, `2` OPEN emitted, `3` termination emitted, `4` OPEN window missed. None of these values means accepted, filled, canceled or flat.

## Complete source

[Download the public Pine example](https://raw.githubusercontent.com/liftx-hq/docs/main/examples/tradingview/one-shot.pine).

```pine theme={null}
//@version=6
indicator("Liftx one-shot demo", overlay = true)

// PRIVATE: this script contains a restricted credential. Never publish/share it.
// Fixed target: link 17, instrument COPY_EXACT_CATALOG_ID.
// The chart supplies signal data; it cannot change this fixed trading target.
// One key is one ordered producer: use a separate setup/key for another alert
// or independent strategy. The same running alert can reuse its key for cycles.
// Never mix this Pine alert with an ordinary OPEN/EXIT alert pair on this key.
// Use an approved demo link. Prepare while disabled; enable only after Liftx
// webhook activation. Set future times in the chart's timezone, then create
// ONE alert: this indicator / Any alert() function call / Liftx webhook URL.
// Changing chart inputs does not update the server's frozen alert copy.
// Never restart/recreate an alert with this setup. Use a new Liftx setup instead.

const int liftxCredentialExpiresAt = 1000
string liftxOpenRequest = ""

// Termination selection does not change the setup's immutable opening policy.
// "One strategy position" uses the exact retained lifecycle reference.
// "This strategy’s positions" includes earlier unresolved cycles from this key.
// "All positions in this market" includes manual and other strategies' Liftx
// positions on the fixed link/instrument and requires the explicit setup grant.
string liftxTerminateSelection = input.string("One strategy position", "On a termination signal", options = ["One strategy position", "This strategy’s positions"])
string liftxTerminateTarget = liftxTerminateSelection == "One strategy position" ? "position" : liftxTerminateSelection == "This strategy’s positions" ? "strategy" : ""
if liftxTerminateTarget == ""
    runtime.error("Invalid termination target. Do not widen scope; use an authorized selection.")

// Every intent uses this one envelope; group targets omit position references.
liftxMessage(string action, string positionRef, int positionStarted, int sequence, int issued, string requestJSON, string target = "position") =>
    string commandID = "11111111-1111-4111-8111-111111111111:" + str.tostring(sequence) + ":" + action
    string message = "{\"token\":\"REPLACE_WITH_RESTRICTED_TRADINGVIEW_KEY\",\"command\":{\"client_command_id\":" + '"' + commandID + '"'
    message += ',"issued_at":' + str.tostring(issued) + ',"expires_at":' + str.tostring(issued + 60)
    message += ',"action":"' + action + '"' + ",\"exchange_link_id\":17,\"instrument_id\":\"COPY_EXACT_CATALOG_ID\",\"source_instance_id\":\"11111111-1111-4111-8111-111111111111\",\"binding_revision\":1"
    message += ',"target":"' + target + '"'
    message += target == "position" ? ',"client_position_id":"' + positionRef + '","position_started_at":' + str.tostring(positionStarted) : ""
    message += ',"sequence":' + str.tostring(sequence)
    message += (requestJSON == "" ? "" : ',"request":' + requestJSON) + '}}'
    message

// Create the alert before OPEN time. Keep its expiration after TERMINATE time.
bool liftxEnabled = input.bool(false, "Enable one-shot demo", tooltip = "Sends one OPEN and one TERMINATE signal. No execution feedback or automatic retry.")
int liftxOpenAt = input.time(0, "OPEN time (chart timezone)")
int liftxTerminateAt = input.time(0, "TERMINATE time (chart timezone)")
const string liftxPositionRef = "11111111-1111-4111-8111-111111111111:one-shot"
int liftxPositionStarted = int(liftxOpenAt / 1000)

// Signal phases only: 0 idle, 1 waiting, 2 OPEN emitted, 3 TERMINATE emitted,
// 4 OPEN window missed. No phase means accepted, filled, canceled, or flat.
// varip retains state across realtime ticks and bars, not script restarts.
varip int liftxPhase = 0
varip int liftxSequence = 0

if barstate.isrealtime and liftxEnabled
    if timenow >= liftxCredentialExpiresAt
        runtime.error("Credential expired. Signals have stopped; inspect Liftx and manage remaining orders or exposure there.")
    if liftxPhase == 0
        if liftxOpenAt <= timenow or liftxTerminateAt < liftxOpenAt + 60000 or liftxTerminateAt >= liftxCredentialExpiresAt
            runtime.error("Choose a future OPEN time and a TERMINATE time at least 60 seconds later, before credential expiry. After interruption, stop the alert and inspect Liftx; do not restart it.")
        liftxPhase := 1
    if liftxPhase == 1 and timenow >= liftxOpenAt
        if timenow >= liftxOpenAt + 60000
            liftxPhase := 4
        else
            liftxSequence += 1
            liftxPhase := 2
            alert(liftxMessage("open", liftxPositionRef, liftxPositionStarted, liftxSequence, int(timenow / 1000), liftxOpenRequest), alert.freq_all)
    else if liftxPhase == 2 and timenow >= liftxTerminateAt
        liftxSequence += 1
        liftxPhase := 3
        alert(liftxMessage("terminate", liftxPositionRef, liftxPositionStarted, liftxSequence, int(timenow / 1000), "", liftxTerminateTarget), alert.freq_all)

// Realtime updates drive both signals; this is not a wall-clock scheduler.
// No automatic rearm or restart recovery.
plot(liftxPhase, "Local signal phase (not execution)", display = display.data_window)

// Missing updates, credential expiry, stopped alerts, or delivery failure can
// prevent termination. Signal state never means accepted, filled, canceled or flat.
// The chart's local state is independent of the server alert and its delivery.
// After an interruption, stop the alert and inspect Activity AND the actual
// positions in Liftx. Manage remaining orders and exposure there.
```

## Before adapting the sample

The generated private copy replaces the dummy `token`, link, catalog ID, source UUID, binding revision and `liftxCredentialExpiresAt`. Guided mode intentionally has an empty `liftxOpenRequest`; Liftx uses the saved opening configuration. Do not turn the public sample into a live sender by changing only its token.

Retain one ordered producer per setup, preserve event identities on delivery retries and never reuse a lifecycle reference for a new position. [Pine setup](/integrations/tradingview/pine), [canonical command fields](/integrations/tradingview/command-format) and [target semantics](/integrations/tradingview/targets-and-lifecycles) explain the contract.

After any interruption, inspect Activity and actual positions, manage remaining orders/exposure and create a fresh source for a new alert. The example has no execution feedback, automatic delivery retry, automatic rearm or restart recovery.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.