CoinScriptSprache
Sprache
Die Referenz zu CoinScript: Datenreihen von Kerzen über Order Flow und Unternehmenszahlen bis On-Chain und Makro, andere Symbole, Funktionen, plot, signal, hline, alertcondition, input, eigene Berechnungen und was ein Script nicht darf.
CoinScript ist JavaScript mit einer festen Bibliothek. Das meiste, was du aus JavaScript kennst, funktioniert: const und let, Funktionen, Pfeilfunktionen, if, Schleifen, Math. Was gesperrt ist, steht unten unter „Was ein Script nicht darf“. Dazu kommen die Datenreihen des Charts und die Funktionen auf dieser Seite. Im Editor findest du dieselbe Übersicht kurz gefasst im Reiter Referenz unter dem Code.
So rechnet ein Script
Ein Script läuft einmal über alle Kerzen, die der Chart geladen hat, nicht Kerze für Kerze.
- Jede Datenreihe ist eine Liste mit genau einem Wert pro Kerze. Index
0ist die älteste Kerze, der letzte Indexbars - 1die neueste, also die laufende. - Fehlende Werte sind
NaN. - Die Funktionen nehmen ganze Reihen und geben ganze Reihen zurück.
ema(close, 21)ist eine Liste mit dem EMA für jede Kerze. - Statt einer Reihe kannst du überall auch eine Zahl übergeben, etwa
cross(close, 85000).
// Der letzte und der vorletzte Schlusskurs
const last = close[bars - 1]
const prev = close[bars - 2]
console.log('Letzter Schluss', last, 'davor', prev)
plot(close, { title: 'Close', overlay: true })Die laufende Kerze ändert sich, bis sie schließt. Was ein Script für die letzte Kerze berechnet, kann sich bis dahin noch ändern, auch ein Signal kann wieder verschwinden.
Lädt der Chart beim Zurückscrollen ältere Kerzen nach, wird die Liste länger und die Indizes verschieben sich. Rechne deshalb immer relativ, etwa mit i - 1 oder bars - 1, nie mit festen Indizes.
Datenreihen
| Name | Inhalt |
|---|---|
open, high, low, close | Eröffnung, Hoch, Tief und Schluss der Kerzen des Charts |
time | Öffnungszeit jeder Kerze in Millisekunden seit 1970 (UTC), für Wochentage, Handelszeiten und feste Zyklen |
volume | Volumen der Chart-Kerzen, summiert über alle Börsen des Charts |
buyVol | Taker-Kaufvolumen je Kerze |
sellVol | Taker-Verkaufsvolumen je Kerze |
delta | Taker-Kauf- minus Taker-Verkaufsvolumen je Kerze |
cvd | Laufende Summe von delta |
oi | Open Interest in Coin, Summe der Börsen |
funding | Funding Rate in % je 8 Stunden, Mittel der Börsen |
liqLong, liqShort | Liquidierte Longs und Shorts je Kerze in USD, Summe der Börsen |
trades | Anzahl der Trades je Kerze |
buyTrades, sellTrades | Anzahl der Käufe und Verkäufe je Kerze (nach Taker-Seite) |
bidDepth, askDepth | Orderbuch: Kauf- und Verkaufsorders innerhalb 1 % um die Mitte des Buchs in USD |
bidWall, askWall | Orderbuch: Preis der größten Kaufwand unter und der größten Verkaufswand über der Mitte |
bidWallSize, askWallSize | Orderbuch: Betrag dieser Wände in USD |
revenue, netIncome, eps | Aktien: Umsatz, Gewinn und Gewinn je Aktie des zuletzt gemeldeten Quartals |
revenueTtm, netIncomeTtm, epsTtm | Aktien: dieselben Zahlen über die letzten zwölf Monate |
pe | Aktien: KGV, also close geteilt durch epsTtm |
revenueEst, epsEst | Aktien: Umsatz und Gewinn je Aktie, die die Analysten für das zuletzt gemeldete Quartal erwartet hatten |
margin, marginTtm | Aktien: Nettomarge in %, je Quartal und über zwölf Monate |
cash | Aktien: liquide Mittel zum letzten Quartalsende |
interest, interestTtm | Aktien: Zinsen plus Dividenden auf Vorzugsaktien, je Quartal und über zwölf Monate |
holdings, mnav | Krypto-Unternehmen: Bestand des größten Coins und mNAV |
bars | Anzahl der Kerzen (eine Zahl, keine Reihe) |
Alle Reihen haben dieselbe Länge wie die Kerzen des Charts und gelten für dessen Symbol und Timeframe. Weitere Datenreihen des Terminals, etwa On-Chain-Werte, Renditen, Notenbanken, ETF-Flüsse oder COT, liest du mit feed(), die Kerzen anderer Symbole mit symbol(). Andere Timeframes und die Uhrzeit der Kerzen kennt ein Script nicht.
Gibt es eine Reihe für das Symbol nicht, etwa Unternehmenszahlen für Bitcoin oder Order Flow für eine Aktie, steht in ihr nur NaN, und die Konsole sagt das.
Order-Flow-Reihen
buyVol, sellVol, delta und cvd beruhen auf dem Taker-Volumen, also darauf, ob ein Trade als Kauf oder Verkauf in den Markt ging.
buyVol + sellVol ist nicht immer gleich volume, das mehrere Börsen enthalten kann. Eine Kerze ohne Taker-Zahl ist NaN. Symbole ohne Order Flow, etwa Aktien oder Devisen, haben in diesen Reihen nur NaN, und die Konsole sagt das.
cvd beginnt mit der ersten geladenen Kerze, die eine Taker-Zahl hat. Sein Niveau hängt also davon ab, wie weit der Chart zurückreicht. Vergleiche den Verlauf, nicht die absolute Höhe.
Open Interest und Funding
oi summiert das Open Interest der Börsen, funding mittelt ihre Funding Rates. Jede Kerze trägt den zuletzt bekannten Wert, funding verläuft deshalb in Stufen. Vor dem ersten bekannten Wert steht NaN.
oi und funding reichen etwa 1.000 Kerzen des Timeframes zurück, mindestens aber einen Tag. Hat der Chart mehr Kerzen geladen, sind sie für die älteren NaN. Beides gibt es nur für Krypto-Perpetuals.
oi ist im Script in Coin angegeben, nicht in Dollar. Bei Alarmen ist Open Interest dagegen in Mio. $.Liquidationen und Trades
liqLong und liqShort sind die liquidierten Long- und Short-Positionen je Kerze in US-Dollar, über alle Börsen summiert, wie im Fenster Liquidationen mit der Quelle „Aggregiert“. trades zählt die Trades je Kerze, buyTrades und sellTrades teilen sie danach, ob der Taker gekauft oder verkauft hat.
Eine Kerze ohne Liquidation hat den Wert 0. NaN heißt: Für diese Kerze gibt es keine Zahl. Die Reihen gibt es für Krypto-Symbole, ab dem Minuten-Timeframe.
// Liquidationen: Longs nach oben, Shorts nach unten, in Mio. $
plot(liqLong.map(v => v / 1e6), { title: 'Longs', style: 'hist', color: '#FF1919' })
plot(liqShort.map(v => -v / 1e6), { title: 'Shorts', style: 'hist', colorDn: '#00FFDA' })
hline(0)Orderbuch
Die Reihen des Orderbuchs sind das, was die Orderbuch-Heatmap und Orderbuch Top Levels zeigen, als Zahlen je Kerze:
| Name | Inhalt |
|---|---|
bidDepth | Kauforders innerhalb 1 % um die Mitte des Buchs in USD, im Mittel der Kerze |
askDepth | Verkaufsorders innerhalb 1 % um die Mitte des Buchs in USD, im Mittel der Kerze |
bidWall | Preis der größten Kaufwand unter der Mitte, bis 5 % entfernt |
askWall | Preis der größten Verkaufswand über der Mitte, bis 5 % entfernt |
bidWallSize, askWallSize | Betrag dieser Wände in USD |
- Mitte des Buchs: der Preis zwischen Kauf- und Verkaufsorders der Kerze.
- Wand: eine Preisstufe von 0,05 % des Kurses, die mindestens doppelt so viel hält wie die Stufen um sie herum. Gewählt wird die, die am weitesten herausragt, wie bei Orderbuch Top Levels. Ohne Wand ist der Wert
NaN. - Zeitraum: aus dem aufgezeichneten Orderbuch, die laufende Kerze aus dem Live-Buch des geöffneten Charts. Vor dem Beginn der Aufzeichnung steht
NaN. Minutenkerzen reichen drei Tage, 5-Minuten-Kerzen 30 Tage und Stundenkerzen ein Jahr zurück. - Wie die Heatmap ist das Orderbuch Teil von Plus und nur für Kryptowährungen da.
// Buch-Ungleichgewicht: über 0 mehr Kauforders, unter 0 mehr Verkaufsorders
const imbalance = bidDepth.map((b, i) => (b - askDepth[i]) / (b + askDepth[i]))
plot(imbalance, { title: 'Ungleichgewicht', style: 'hist', color: '#00FFDA', colorDn: '#FF1919' })
hline(0)
// Die größten Wände als Linien im Preischart
plot(bidWall, { title: 'Kaufwand', color: '#00FFDA', overlay: true })
plot(askWall, { title: 'Verkaufswand', color: '#FF1919', overlay: true })
// Alarm, wenn der Kurs bis auf 0,3 % an die Kaufwand kommt
alertcondition(close.map((c, i) => (c - bidWall[i]) / c < 0.003), { title: 'Kurs an der Kaufwand' })Unternehmenszahlen
Auf Aktien liest ein Script die Zahlen, die auch die Indikatoren unter Unternehmen zeigen:
| Name | Inhalt |
|---|---|
revenue | Umsatz des zuletzt gemeldeten Quartals |
netIncome | Gewinn (Nettoergebnis) des zuletzt gemeldeten Quartals |
eps | Gewinn je Aktie (verwässert) des zuletzt gemeldeten Quartals |
revenueTtm, netIncomeTtm, epsTtm | dieselben Zahlen über die letzten zwölf Monate |
pe | KGV: close geteilt durch epsTtm |
revenueEst | Umsatz, den die Analysten für das zuletzt gemeldete Quartal erwartet hatten |
epsEst | Gewinn je Aktie, den die Analysten für das zuletzt gemeldete Quartal erwartet hatten |
margin, marginTtm | Nettomarge in % (netIncome geteilt durch revenue), je Quartal und über zwölf Monate; na, wo der Gewinn größer als der Umsatz oder der Umsatz kaum vorhanden ist |
cash | Liquide Mittel: Bargeld und kurzfristige Geldanlagen zum letzten Quartalsende, bei Strategy die wöchentlich gemeldete USD-Reserve |
interest, interestTtm | Zinsen plus Dividenden auf Vorzugsaktien, je Quartal und über zwölf Monate |
- Ab dem Berichtstag: Jede Zahl steht ab dem Tag, an dem das Unternehmen sie veröffentlicht hat, und bleibt bis zum nächsten Bericht stehen. Die Reihe verläuft in Stufen. Davor steht
NaN. - Ein neuer Bericht ist eine Kerze, an der sich der Wert gegenüber der Kerze davor ändert, etwa
revenue[i] !== revenue[i - 1]. - Einheit:
revenueundnetIncomein der Berichtswährung des Unternehmens, meist US-Dollar. Für Milliarden teilst du durch1e9. - Zwölf Monate: Die Werte mit
Ttmreichen weiter zurück als die Quartalswerte und glätten saisonale Schwankungen. - KGV:
peteilt jeden Schlusskurs durch den zuletzt gemeldeten Gewinn je Aktie über zwölf Monate. Ohne positiven Gewinn ist esNaN. - Erwartungen:
revenueEstundepsEstsind die Erwartungen, mit denen der Markt in den jeweiligen Bericht ging.epsEstist meist auf bereinigter Basis geschätzt,epsist der Gewinn nach Bilanzregeln. - Für Krypto, Fonds, Indizes und Devisen sind diese Reihen
NaN.
// Umsatz über zwölf Monate in Mrd. im eigenen Fenster
plot(revenueTtm.map(v => v / 1e9), { title: 'Umsatz 12 M (Mrd.)', color: '#00FFDA' })Ein vollständiges Beispiel, das Berichte mit steigendem Umsatz bei fallendem Kurs markiert, steht unter Beispiele.
Krypto-Unternehmen
| Name | Inhalt |
|---|---|
holdings | Bestand des größten Coins in Stück (BTC bei Strategy und Metaplanet, ETH bei BitMine), ab jedem Kauf oder Verkauf |
mnav | Unternehmenswert (Börsenwert plus Schulden und Vorzugsaktien, abzüglich liquider Mittel) durch den Wert der Coins je Kerze, wie Strategy ihn ausweist; 1 heißt: genau der Wert der Coins |
Für Unternehmen ohne Coins in der Bilanz sind beide NaN. Für Miner liest du die Netzdaten mit feed():
// Hashprice in USD je PH/s und Tag
const einnahmen = feed('btc-miner-revenue')
const hashrate = feed('btc-hashrate')
plot(einnahmen.map((v, i) => v / (hashrate[i] / 1000)), { title: 'Hashprice', color: '#00FFDA' })Weitere Datenreihen mit feed
feed('name') liefert eine weitere Datenreihe des Terminals als Reihe mit einem Wert je Kerze, etwa feed('btc-sopr') oder feed('us10y').
- Ausrichtung: Jede Kerze trägt den zuletzt bekannten Wert. Tages-, Wochen- und Monatswerte stehen ab dem Tag, für den sie gelten. Vor dem ersten Wert steht
NaN. - Veraltete Werte: Kommt nach einem Wert länger kein neuer, steht danach
NaNstatt des alten Werts: bei Renditen und anderen Werten der Handelstage nach fünf Tagen, bei den Tageswerten des Krypto-Markts nach zwei bis drei Tagen, bei Wochenwerten nach zwei Wochen, bei Monatswerten nach etwa drei Monaten. Ein ETF-Nettozufluss gilt nur für seinen Tag. On-Chain-Werte und Leitzinsen gelten bis zum nächsten Wert. - Unabhängig vom Chart: Die Reihen sind dieselben, egal auf welchem Symbol das Script läuft.
// SOPR mit der 1 als Grenze und einer Alarm-Bedingung
const sopr = feed('btc-sopr')
plot(sopr, { title: 'SOPR', color: '#FFEB3B' })
hline(1)
alertcondition(sopr.map((v, i) => i > 0 && sopr[i - 1] < 1 && v >= 1), 'SOPR über 1')us-cpi oder us-m2 erscheinen erst Wochen nach dem Monat, für den sie gelten. Im Backtest stehen sie trotzdem ab dem ersten Tag ihres Monats. Rechne damit, wenn eine Strategie auf ihnen beruht.Diese Namen gibt es:
On-Chain
| Name | Inhalt | Einheit |
|---|---|---|
btc-mvrv-z | Bitcoin MVRV Z-Score | – |
eth-mvrv-z | Ethereum MVRV Z-Score | – |
btc-sopr | Bitcoin SOPR | – |
btc-netflow | Bitcoin Börsen-Netflow je Tag | USD |
eth-netflow | Ethereum Börsen-Netflow je Tag | USD |
btc-exchange-supply | Bitcoin auf Börsen | BTC |
eth-exchange-supply | Ether auf Börsen | ETH |
btc-active-addresses | Bitcoin aktive Adressen | Adressen |
eth-active-addresses | Ethereum aktive Adressen | Adressen |
btc-hashrate | Bitcoin Hashrate | TH/s |
btc-difficulty | Bitcoin Mining-Difficulty | – |
btc-supply | Bitcoin im Umlauf | BTC |
btc-tx-fees | Bitcoin Transaktionsgebühren je Tag | USD |
btc-miner-revenue | Bitcoin Miner-Einnahmen je Tag | USD |
Krypto-Markt
| Name | Inhalt | Einheit |
|---|---|---|
btc-marketcap | Bitcoin-Marktkapitalisierung | USD |
usdt-marketcap | USDT-Marktkapitalisierung | USD |
stablecoin-cap | Stablecoin-Marktkapitalisierung | USD |
btc-dominance | Bitcoin-Dominanz | % |
usdt-dominance | USDT-Dominanz | % |
fear-greed | Fear & Greed Index | 0–100 |
ETF-Flüsse
| Name | Inhalt | Einheit |
|---|---|---|
btc-etf-flow | Bitcoin-ETFs Nettozufluss je Tag | USD |
eth-etf-flow | Ether-ETFs Nettozufluss je Tag | USD |
btc-etf-assets | Bitcoin-ETFs verwaltetes Vermögen | USD |
Zinsen und Anleihen (USA)
| Name | Inhalt | Einheit |
|---|---|---|
us1m | US-Rendite 1 Monat | % |
us3m | US-Rendite 3 Monate | % |
us6m | US-Rendite 6 Monate | % |
us1y | US-Rendite 1 Jahr | % |
us2y | US-Rendite 2 Jahre | % |
us3y | US-Rendite 3 Jahre | % |
us5y | US-Rendite 5 Jahre | % |
us7y | US-Rendite 7 Jahre | % |
us10y | US-Rendite 10 Jahre | % |
us20y | US-Rendite 20 Jahre | % |
us30y | US-Rendite 30 Jahre | % |
us10y2y | Zinskurve 10 Jahre minus 2 Jahre | % |
us10y-inflation | Inflationserwartung 10 Jahre | % |
us10y-real | Realrendite 10 Jahre | % |
hy-spread | High-Yield-Spread | % |
baa-spread | Baa-Spread über 10 Jahre | % |
Geld und Notenbanken
| Name | Inhalt | Einheit |
|---|---|---|
us-m2 | US-Geldmenge M2 | Mrd. USD |
fed-balance | Fed-Bilanzsumme | Mio. USD |
tga | Treasury General Account | Mio. USD |
rrp | Overnight Reverse Repo | Mrd. USD |
ecb-balance | EZB-Bilanzsumme | Mio. EUR |
boj-balance | BoJ-Bilanzsumme | 100 Mio. JPY |
fed-funds | Fed Funds Rate, Monatsmittel | % |
fed-target-upper | Fed-Zielkorridor, oberer Rand | % |
fed-target-lower | Fed-Zielkorridor, unterer Rand | % |
policy-rate-us | Leitzins USA | % |
policy-rate-eur | Leitzins Eurozone | % |
policy-rate-jp | Leitzins Japan | % |
policy-rate-au | Leitzins Australien | % |
Wirtschaft (USA)
| Name | Inhalt | Einheit |
|---|---|---|
us-cpi | US-Verbraucherpreisindex | Index |
us-core-cpi | US-Kernverbraucherpreisindex, unbereinigt | Index |
us-unemployment | US-Arbeitslosenquote | % |
us-industrial | US-Industrieproduktion | Index |
us-dollar-broad | US-Dollar-Index, breit | Index |
COT-Positionierung
cot-<markt>-<gruppe> ist die Nettoposition einer Händlergruppe (Long minus Short) in Kontrakten, aus dem wöchentlichen COT-Bericht, etwa feed('cot-btc-lev'). Jeder Wert steht ab dem Stichtag des Berichts (dienstags), veröffentlicht wird er am Freitag darauf.
| Märkte | Gruppen |
|---|---|
btc, mbt, eth, met, sol, xrp, es, nq, zn, zt, zq, eur, jpy, gbp, dxy | dealer Dealer / Intermediäre, am Asset Manager, lev Leveraged Funds, oth Sonstige Meldepflichtige, nr Nicht meldepflichtig |
gc Gold, si Silber, hg Kupfer, cl Rohöl WTI, ng Erdgas | pm Produzenten / Händler, sd Swap Dealer, mm Managed Money, oth Sonstige Meldepflichtige, nr Nicht meldepflichtig |
Die Märkte heißen wie im COT-Widget: btc CME Bitcoin, mbt CME Micro Bitcoin, eth CME Ether, met CME Micro Ether, sol CME Solana, xrp CME XRP, es S&P 500 E-mini, nq Nasdaq-100 E-mini, zn 10J T-Note, zt 2J T-Note, zq Fed Funds, eur Euro FX, jpy Japanischer Yen, gbp Britisches Pfund, dxy US-Dollar-Index.
Andere Symbole mit symbol
symbol('name') liefert die Kerzen eines anderen Symbols im Timeframe des Charts als Objekt mit den Reihen open, high, low, close und volume.
// Ether gegen Bitcoin: der Kurs von ETH geteilt durch den des Charts
const eth = symbol('ETH')
plot(eth.close.map((c, i) => c / close[i]), { title: 'ETH / Chart', color: '#B28CFF' })- Welche Namen: jedes Symbol der Symbolsuche, so wie du es dort eintippst: Krypto (
'ETH','SOL'), Aktien ('AAPL'), Indizes ('SPX'), Devisen ('EURUSD'), Rohstoffe ('XAU'), Anleihen ('US10Y'), Wirtschaftsdaten ('USIRYY'), Unternehmen vor dem Börsengang ('OPENAI','ANTHROPIC': ihre Bewertung in Mrd. US-Dollar, je Tag; nach dem Börsengang der Kurs der Aktie), Ratios ('ETH/BTC') und Spreads ('BTC-ETH'). - Ausrichtung nach Zeit: Jede Kerze des Charts trägt die letzte Kerze des Symbols, die zur selben Zeit oder davor begonnen hat. Handelt das Symbol nicht, etwa eine Aktie am Wochenende, stehen dort die Werte seiner letzten Kerze davor, auch beim Volumen. Vor seiner ersten Kerze steht
NaN. - Wie weit zurück: so weit wie der Chart, solange das Symbol so lange Kerzen hat.
Was feed und symbol brauchen
Ein Script läuft ohne Netzwerk. Das Terminal lädt die Daten für feed() und symbol() deshalb vor dem Lauf, und dafür muss der Name im Code stehen:
- Schreib den Namen als Text in Anführungszeichen direkt in den Aufruf:
feed('btc-sopr'), nichtfeed(name). Ein berechneter Name ist ein Fehler. - Ein Script liest höchstens 8 verschiedene Namen in
feed()undsymbol()zusammen. - Ein unbekannter Name ist ein Fehler mit der Zeile. Die Meldung schlägt ähnliche Namen vor.
- Speichere das Ergebnis in einer Konstante, etwa
const eth = symbol('ETH'), statt die Funktion in einer Schleife aufzurufen.
const eps = 1e-9, gilt im ganzen Script deine. Nenn sie anders, wenn du die Reihe brauchst.Funktionen
| Funktion | Ergebnis |
|---|---|
sma(serie, länge) | Einfacher gleitender Durchschnitt |
ema(serie, länge) | Exponentieller gleitender Durchschnitt |
rsi(serie, länge) | Relative Strength Index nach Wilder, länge ist ohne Angabe 14 |
stdev(serie, länge) | Standardabweichung über das Fenster |
zscore(serie, länge) | Abstand vom Durchschnitt in Standardabweichungen |
highest(serie, länge) | Höchster Wert der letzten länge Kerzen |
lowest(serie, länge) | Tiefster Wert der letzten länge Kerzen |
change(serie, n) | Differenz zum Wert n Kerzen vorher, n ist ohne Angabe 1 |
cross(a, b) | true an jeder Kerze, an der a und b sich kreuzen |
feed('name') | Eine weitere Datenreihe des Terminals, siehe oben |
symbol('name') | Kerzen eines anderen Symbols, siehe oben |
Genauer:
smaistNaN, bis genug Werte da sind. Enthält das Fenster eine Lücke (NaN), ist auch der DurchschnittNaN, das nächste volle Fenster liefert wieder eine Zahl.emastartet mit dem ersten Wert der Reihe und glättet mit dem Faktor2 / (länge + 1). Die ersten Werte sind deshalb noch ungenau. Lücken überspringt der EMA.rsiliefert den ersten Wert nachlängeKursänderungen. Eine Lücke zählt als unveränderter Wert.stdevteilt durchlänge(Standardabweichung der Grundgesamtheit).zscoreist(wert − sma) / stdevüber dasselbe Fenster.highestundlowestschließen die aktuelle Kerze ein und überspringenNaN. Am Anfang der Reihe nehmen sie die Kerzen, die es schon gibt.changeist für die erstennKerzenNaN.nmuss eine ganze Zahl sein.crosserkennt Kreuzungen in beide Richtungen und liefert eine Liste mittrueundfalse. Liegen beide an einer Kerze genau gleich auf, zählt das nicht als Kreuzung.
Für eine Richtung vergleichst du selbst:
// Kreuzung nur nach oben bzw. nur nach unten
const fast = ema(close, 9)
const slow = ema(close, 21)
const up = fast.map((f, i) => i > 0 && fast[i - 1] <= slow[i - 1] && f > slow[i])
const down = fast.map((f, i) => i > 0 && fast[i - 1] >= slow[i - 1] && f < slow[i])
signal(up, { title: 'Nach oben', color: '#00FFDA', pos: 'below' })
signal(down, { title: 'Nach unten', color: '#FF1919', pos: 'above' })Zeichnen und Signale
plot
plot(serie, { title, color, colorDn, overlay, style }) zeichnet eine Reihe.
| Option | Bedeutung | Ohne Angabe |
|---|---|---|
title | Name in der Legende, bis 60 Zeichen | „Plot 1“, „Plot 2“ … |
color | Farbe der Linie bzw. der positiven Balken | '#FFFCF0' |
colorDn | Farbe der negativen Balken im Histogramm | '#FF1919' |
overlay | true zeichnet in den Preischart | eigenes Fenster |
style | 'hist' zeichnet ein Histogramm | Linie |
- Alle Plots ohne
overlay: trueteilen sich ein Fenster unter dem Chart. Seine Skala passt sich den sichtbaren Werten an. - Im Preischart sind Plots immer Linien und nutzen die Preisskala. Die Skala richtet sich weiter nach den Kerzen: Eine Reihe in einer anderen Einheit, etwa
cvd, liegt dann außerhalb des sichtbaren Bereichs. Leg solche Reihen in ein eigenes Fenster. - Die Farbe des ersten Plots erscheint in der Legende. Script-Alarme, die mit einem Wert vergleichen, nutzen ebenfalls den ersten Plot.
Farben gibst du als Hex-Wert an. Die Hausfarben des Terminals sind #00FFDA (Kauf, steigend), #FF1919 (Verkauf, fallend), #FFEB3B (Hinweis) und #FFFCF0 (neutral).
hline
hline(wert, { color }) zieht eine gestrichelte waagrechte Linie im Fenster des Scripts, etwa bei 0, 30 oder 70. Im Preischart erscheint sie nicht, sie braucht also mindestens einen Plot ohne overlay.
signal
signal(bedingung, { title, color, pos }) setzt an jeder Kerze, an der bedingung wahr ist, ein Dreieck.
| Option | Bedeutung | Ohne Angabe |
|---|---|---|
title | Name des Signals, auch für Alarme | 'Signal' |
color | Farbe des Dreiecks | '#FFEB3B' |
pos | 'below' unter das Tief, 'above' über das Hoch | 'below' |
Im Backtest sind Signale mit pos: 'below' Long-Einstiege und Signale mit pos: 'above' Short-Einstiege.
alertcondition
alertcondition(bedingung, { title }) zeichnet nichts. Es legt eine Bedingung fest, auf die du im Alarm-Dialog einen Script-Alarm setzen kannst. Statt des Objekts geht auch nur der Titel: alertcondition(bedingung, 'Ausbruch'). Ohne Titel heißt sie „Bedingung 1“, „Bedingung 2“ …
Als Bedingung eignet sich jede Liste aus true und false oder 1 und 0, etwa das Ergebnis von cross() oder von close.map(…).
Einstellbare Werte mit input
input(name, standard) macht eine Zahl einstellbar und gibt ihren aktuellen Wert zurück.
const len = input('Länge', 21)
const k = input('Faktor', 2.5)
const mid = ema(close, len)
const sd = stdev(close, len)
plot(mid, { title: 'EMA', overlay: true })
plot(mid.map((v, i) => v + k * sd[i]), { title: 'Oben', overlay: true })sd einmal vor dem map aus, nicht darin. Ein stdev() innerhalb von map würde für jede Kerze die ganze Reihe neu berechnen und das Zeitlimit sprengen.- Im Chart erscheinen die Werte in den Einstellungen des Indikators unter Eingaben. Ganze Zahlen stellst du in Einerschritten ein, Zahlen mit Nachkommastellen in der Feinheit des Standards (bei
2.5also in Schritten von 0,1). - Der Name ist zugleich die Beschriftung, bis 40 Zeichen. Jeder Name zählt einmal.
- Nur Zahlen werden zu Einstellungen. Ein anderer Standard, etwa ein Text, kommt unverändert zurück.
- Script-Alarme rechnen immer mit dem Standard. Die Optimierung variiert die ersten beiden Eingaben.
input('Länge', 21). Nur dann kann die Optimierung mit Übernehmen den besten Wert in deinen Code schreiben.Ausgaben in die Konsole
console.log(…) schreibt in die Konsole des Editors, console.warn(…) in Gelb, console.error(…) in Rot. Eine Reihe erscheint mit ihren letzten fünf Werten und ihrer Länge, etwa [… 125, 126, 127, 128, 129] (30). Pro Lauf zeigt die Konsole bis zu 50 Ausgaben mit je 300 Zeichen.
Die Ausgaben erscheinen nur bei Ausführen. Wenn das Script im Chart läuft, schreibt es nichts in die Konsole.
Eigene Reihen berechnen
Rechenzeichen wirken nicht auf ganze Reihen: close - open ergibt keine Liste, sondern NaN. Für eigene Reihen gehst du mit map über jede Kerze. Der zweite Parameter ist der Index:
// Kerzenkörper in Prozent: (close − open) / open
const body = close.map((c, i) => (c - open[i]) / open[i] * 100)
plot(body, { title: 'Körper %', style: 'hist', color: '#00FFDA', colorDn: '#FF1919' })
hline(0)map auf einer Datenreihe liefert wieder eine Liste von Zahlen, true und false werden dabei zu 1 und 0. So entstehen Bedingungen für signal() und alertcondition(). Greifst du an der ersten Kerze auf close[i - 1] zu, bekommst du undefined, und die Rechnung ergibt NaN. Das ist in Ordnung, die Kerze zeigt dann nichts.
Für Rechnungen, die den Wert der Vorkerze brauchen, eignet sich eine Schleife:
// Average True Range, einfach gemittelt
const tr = new Array(bars).fill(NaN)
for (let i = 1; i < bars; i++) {
tr[i] = Math.max(high[i] - low[i], Math.abs(high[i] - close[i - 1]), Math.abs(low[i] - close[i - 1]))
}
plot(sma(tr, input('Länge', 14)), { title: 'ATR', color: '#FFEB3B' })plot(), signal() und alertcondition() immer eine Liste mit einem Wert pro Kerze. Eine kürzere Liste, etwa aus close.slice(-50), beginnt bei der ältesten Kerze und passt dann nicht mehr zu den Kerzen.Eigene Hilfsfunktionen schreibst du mit function oder als Pfeilfunktion. Zur Verfügung stehen außerdem Math, Number, String, Boolean, Object, Array, JSON, Date, Map, Set und die typisierten Arrays wie Float64Array.
Was ein Script nicht darf
Scripts laufen abgeschottet im Browser. Die Daten auf dieser Seite lädt das Terminal vor dem Lauf selbst. Der Editor lehnt ab:
importundexport,- eigenes Netzwerk und eigenen Speicher:
fetch,XMLHttpRequest,WebSocket,localStorageund Ähnliches gibt es in einem Script nicht, - Timer und Nebenläufigkeit:
setTimeout,setInterval,Promise,async-Funktionen und Generatoren, thisaußerhalb einer Funktion,with,debuggerund Klassen,- die Namen
globalThis,self,window,eval,Function,constructor,prototypeund__proto__, auch als Eigenschaft oder in einem Text.
Häufige Meldungen
| Meldung | Bedeutung |
|---|---|
| „name“ ist nicht definiert | Tippfehler, oder der Name gehört nicht zu CoinScript |
| Syntaxfehler: Unerwartetes Zeichen | Eine Klammer, ein Komma oder ein Anführungszeichen fehlt oder ist zu viel |
| „window“ ist in CoinScript nicht erlaubt | Ein gesperrter Name, siehe oben |
| fetch ist keine Funktion | Eigene Netzwerkzugriffe gibt es in CoinScript nicht. Daten liest du mit den Reihen oben, feed() und symbol() |
| Unbekannte Datenreihe „…“ in feed() | Tippfehler im Namen. Die Meldung nennt ähnliche Namen, alle stehen oben |
| Unbekanntes Symbol „…“ in symbol() | Das Symbol gibt es in der Symbolsuche nicht. Die Meldung nennt ähnliche |
| feed() braucht den Namen als Text in Anführungszeichen | Der Name ist berechnet, etwa feed(name). Schreib ihn direkt hinein: feed('btc-sopr') |
| Höchstens 8 verschiedene Namen in feed() und symbol() je Script | Teile das Script auf |
| Keine Daten für revenue bei BTC: die Werte bleiben leer. | Die Reihe gibt es für dieses Symbol nicht, oder es kam für diese Kerzen kein Wert. Das Script läuft trotzdem |
| Zuweisung an eine Konstante | Einer const wurde ein neuer Wert gegeben, nimm let |
| Zu viele plot()-Aufrufe (höchstens 24) | Meist ein plot() in einer Schleife |
| Speicherlimit: höchstens 5.000.000 Werte je Array | Ein Array ist zu groß geworden |
| Script abgebrochen: Zeitlimit überschritten | Das Script rechnet länger als 250 ms, etwa wegen einer Endlosschleife |
| CoinScript konnte nicht gestartet werden | Die Rechenumgebung hat nicht geladen. Lade die Seite neu |
Fehler im Code nennen Zeile und Spalte. Ein Klick auf die Meldung in der Konsole setzt den Cursor an die Stelle.