本文へ移動
← すべてのサンプル

サンプル 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(());
}