본문으로 건너뛰기
← 모든 예제

예제 47

Live vwap reversion

the VWAP third-deviation reversion of `46_vwap_3sd_reversion.tzs` (a bar closes beyond the third deviation of the session VWAP; the target

분류
Host: 터미널의 데이터와 엔진 필요
권한
orders.submit
실행하기 전에
a chart in hand on the live market or a replay, whose instrument the live feed serves (aggregated prints and closed bars)
하는 일
asks the terminal to run the strategy on that market; once running it places orders on the account the person chose.
실행 방법
Add script on the Market Replay window or the title bar's script icon (replay or real time); Insert strategy in the Datasets window (backtest).
언어
>=0.1.1, <0.2.0
호스트
>=0.1.8, <0.2.0
필요한 것
features >=0.1.3, <0.2.0trade >=0.1.0, <0.2.0

소스

// Purpose: the VWAP third-deviation reversion of `46_vwap_3sd_reversion.tzs` (a bar closes beyond the third deviation of the session VWAP; the target
// is the second deviation, the stop is 1:1), **handed to the terminal to run where this script is started**: on a replay, on the live market in
// real time, or -- inserted in the Datasets window -- as a backtest over the datasets chosen. One script, one line, the same strategy and rules.
//
// `trade.run` returns at once. The terminal then tells the person what the script reads (the session's VWAP and its spread need the session's
// prints) and asks whether to load them -- computed on this machine, on demand -- before it starts; and which account it trades is the person's
// choice where they started the script (a replay's practice account, the demo account, or the real one if they switched it on), never the script's.
// Category: host
// Permissions: orders.submit
// Preconditions: a chart in hand on the live market or a replay, whose instrument the live feed serves (aggregated prints and closed bars)
// Side effects: asks the terminal to run the strategy on that market; once running it places orders on the account the person chose.
// Run: Add script on the Market Replay window or the title bar's script icon (replay or real time); Insert strategy in the Datasets window (backtest).

lang ">=0.1.1, <0.2.0";
host "ttt" ">=0.1.8, <0.2.0";
requires "features" ">=0.1.3, <0.2.0";
requires "trade" ">=0.1.0, <0.2.0";

strategy vwap_3sd_reversion(entry_k: Decimal, target_k: Decimal, size: Quantity) version "1.0.0" {
    // What the market is doing: the last print, the last closed bar, the VWAP and its spread.
    let px = features.price(features.Source.AggTrades);
    let bar = features.bar_close();
    let vw = features.vwap(features.Source.AggTrades);
    let sd = features.vwap_spread(features.Source.AggTrades);
    let lower = vw - entry_k * sd;
    let upper = vw + entry_k * sd;

    // True on the one step where a new bar has closed -- so a bar is looked at once, not at every print until the next one.
    let new_bar = bar != prev(bar);

    // The open trade, as it was decided: which side, at what price, and where the VWAP and its spread were then.
    let held = features.position_sign();
    let entry = features.entry_price();
    let entry_vw = features.entry_vwap(features.Source.AggTrades);
    let entry_sd = features.entry_spread(features.Source.AggTrades);
    let long_target = entry_vw + target_k * entry_sd;
    let long_stop = entry - (long_target - entry);
    let short_target = entry_vw - target_k * entry_sd;
    let short_stop = entry + (entry - short_target);

    rule long_target_hit when exposure_is(Exposure.Open) && held > 0 && px >= long_target
        => order(Side.Sell, Intent.Close, OrderType.Market, Sizing.Fixed(size));
    rule long_stop_hit when exposure_is(Exposure.Open) && held > 0 && px <= long_stop
        => order(Side.Sell, Intent.Close, OrderType.Market, Sizing.Fixed(size));
    rule short_target_hit when exposure_is(Exposure.Open) && held < 0 && px <= short_target
        => order(Side.Buy, Intent.Close, OrderType.Market, Sizing.Fixed(size));
    rule short_stop_hit when exposure_is(Exposure.Open) && held < 0 && px >= short_stop
        => order(Side.Buy, Intent.Close, OrderType.Market, Sizing.Fixed(size));

    rule enter_long when exposure_is(Exposure.Flat) && new_bar && bar < lower
        => order(Side.Buy, Intent.Open, OrderType.Market, Sizing.Fixed(size));
    rule enter_short when exposure_is(Exposure.Flat) && new_bar && bar > upper
        => order(Side.Sell, Intent.Open, OrderType.Market, Sizing.Fixed(size));
    flatten_on_stop;
}

fn main() -> Result<Unit, Error> {
    // The target on the second deviation FARTHEST from the entry (2.0); -2.0 puts it on the nearest.
    let run = trade.run(vwap_3sd_reversion(3.0, 2.0, qty(0.01)))?;
    print(run.name + " on " + run.target + ": " + run.state);
    return Ok(());
}