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

예제 02

Position sizing

Position sizing from a risk budget, rounded the way an exchange wants: prices to the tick, quantities down to the lot step (never up).

분류
Pure: 어디서나 실행
권한
없음
언어
>=0.1.1, <0.2.0

소스

// Category: pure
// Permissions: none
// Position sizing from a risk budget, rounded the way an exchange wants:
// prices to the tick, quantities down to the lot step (never up).

lang ">=0.1.1, <0.2.0";
import std.fin;

/// How much to buy so that hitting `stop` loses at most `risk`.
fn size_for(risk: Money, entry: Price, stop: Price, step: Quantity) -> Result<Quantity, Error> {
    let loss_per_unit = entry - stop;
    if loss_per_unit.amount() <= 0.0 {
        return Err(error("E-SIZE", "the stop must be below the entry for a long"));
    }
    let raw = risk.amount() / loss_per_unit.amount();
    return Ok(fin.floor_to_step(qty(raw), step));
}

fn main() -> Result<Unit, Error> {
    let tick = price(0.10, USDT);
    let entry = fin.round_to_tick(price(64012.37, USDT), tick);
    let stop = fin.round_to_tick(price(63500.04, USDT), tick);
    print("entry " + to_string(entry) + ", stop " + to_string(stop));
    let size = size_for(money(100, USDT), entry, stop, qty(0.001))?;
    print("size " + to_string(size));
    print("at risk " + to_string((entry - stop) * size));
    print("move to stop " + to_string(fin.pct_change(entry, stop)));
    match size_for(money(100, USDT), stop, entry, qty(0.001)) {
        Ok(_) => print("accepted"),
        Err(e) => print(e.code + ": " + e.message),
    }
    return Ok(());
}
// expect-output: entry 64012.40 USDT, stop 63500.00 USDT
// expect-output: size 0.195
// expect-output: at risk 99.91800 USDT
// expect-output: move to stop -0.008004699089551399
// expect-output: E-SIZE: the stop must be below the entry for a long