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

예제 40

Carry scanner

the carry scanner: reads funding and basis (mark against index) for every symbol the terminal offers, ranks them, and opens a

분류
Host: 터미널의 데이터와 엔진 필요
권한
market.readworkspace.readworkspace.write
실행하기 전에
a terminal connected to a backend that captures funding for the symbols it offers
하는 일
OPENS up to three charts (1h) of the symbols it ranks first, unless already open.
실행 방법
grant market.read, workspace.read and workspace.write, Run.
언어
>=0.1.1, <0.2.0
호스트
>=0.1.7, <0.2.0
필요한 것
derivs >=0.1.0, <0.2.0workspace >=0.1.0, <0.2.0event >=0.1.0, <0.2.0

소스

// Purpose: the carry scanner: reads funding and basis (mark against index) for every symbol the terminal offers, ranks them, and opens a
// chart for the three with the most extreme funding. **A symbol the capture has no reading for is left out and counted, never ranked on a
// guess**; a symbol whose funding the venue did not publish is ranked on nothing.
// Category: host
// Permissions: market.read, workspace.read, workspace.write
// Preconditions: a terminal connected to a backend that captures funding for the symbols it offers
// Side effects: OPENS up to three charts (1h) of the symbols it ranks first, unless already open.
// Run: grant market.read, workspace.read and workspace.write, Run.

lang ">=0.1.1, <0.2.0";
host "ttt" ">=0.1.7, <0.2.0";
requires "derivs" ">=0.1.0, <0.2.0";
requires "workspace" ">=0.1.0, <0.2.0";
requires "event" ">=0.1.0, <0.2.0";
import std.fin;
import std.list;

struct Row {
    symbol: String,
    funding: Float,
    basis: Float,
}

fn main() -> Result<Unit, Error> {
    let now = event.current().time;
    let mut rows: List<Row> = [];
    let mut unknown = 0;
    for symbol in workspace.symbols() {
        let reading = derivs.at(symbol, now)?;
        match reading.funding_rate {
            Some(rate) => {
                match reading.mark {
                    Some(mark) => {
                        match reading.index {
                            Some(index) => {
                                rows.push(Row { symbol: symbol, funding: to_float(rate.value()), basis: to_float(fin.pct_change(index, mark).value()) });
                            }
                            None => {
                                unknown = unknown + 1;
                            }
                        }
                    }
                    None => {
                        unknown = unknown + 1;
                    }
                }
            }
            None => {
                unknown = unknown + 1;
            }
        }
    }
    print(to_string(rows.len()) + " symbols read, " + to_string(unknown) + " with no usable reading (left out)");
    if rows.is_empty() {
        return Ok(());
    }

    // The three with the largest funding in either direction, by selection: a list the language sorts only by its own order.
    let mut taken: List<String> = [];
    let mut rank = 0;
    while rank < 3 && rank < rows.len() {
        let mut best: Option<Row> = None;
        let mut best_size: Float = -1.0;
        for row in rows {
            let size = if row.funding < 0.0 { 0.0 - row.funding } else { row.funding };
            if size > best_size && !list.contains(taken, row.symbol) {
                best_size = size;
                best = Some(row);
            }
        }
        let pick = best.expect("one is left");
        taken.push(pick.symbol);
        print(to_string(rank + 1) + ". " + pick.symbol + ": funding " + to_string(pick.funding * 100.0) + " %, basis " + to_string(pick.basis * 100.0) + " %");
        let mut open = false;
        for chart in workspace.charts() {
            if chart.symbol == pick.symbol {
                open = true;
            }
        }
        if !open {
            match workspace.open_chart(pick.symbol, "1h") {
                Ok(_) => print("   opened a chart"),
                Err(e) => print("   not opened: " + e.code),
            }
        }
        rank = rank + 1;
    }
    return Ok(());
}