Ein Beispiel:
var lineColor = na
n = if bar_index > 10 and bar_index <= 20
lineColor := color.green
else if bar_index > 20 and bar_index <= 30
lineColor := color.blue
else if bar_index > 30 and bar_index <= 40
lineColor := color.orange
else if bar_index > 40
lineColor := color.black
else
lineColor := color.red
plot(close, title="close", color=n, linewidth=5, overlay=true)
plotchar(true, title="bar_index", char=str.tostring(bar_index), location=location.abovebar, color=color.red, overlay=true)
Wichtig: Ausdrücke, die für die Beurteilung verwendet werden, die einen Boole-Wert zurückgeben. Bitte beachten Sie die Verkleinerung. Es kann maximal nur eine Else-Abteilung geben. Alle Branch-Expressionen sind nicht wahr und keine Else-Abteilung gibt es, die na zurückgibt.
x = if close > open
close
plot(x, title="x")
Da der if-Ausdruck nach dem if-Satz false ist, wenn die K-Linie BAR die Centauri ist, also close < open, wird der lokale Codeblock für if nicht ausgeführt. Auch in diesem Fall gibt es keinen Else-Branch. Der if-Ausdruck gibt na zurück.
Die Switch-Anweisung ist auch eine verzweigte Struktur, die verwendet wird, um verschiedene Wege zu entwerfen, die unter bestimmten Bedingungen ausgeführt werden.
1, wie auch die Switch-Sprache und die if-Sprache, kann einen Wert zurückgeben. 2. Im Gegensatz zu anderen Sprachen, in denen die Switch-Sprache nur einen lokalen Block in ihrem Code ausführt, ist eine Break-Ankündigung unnötig (d. h. es ist kein Schlüsselwort wie break erforderlich). 3. Jeder Branch des Switches kann einen lokalen Codeblock schreiben, dessen letzte Zeile den zurückgegebenen Wert ist. 4. Beurteilen Sie die Position der Ausdrücke in der Switch-Struktur und schreiben Sie Strings, Variablen, Ausdrücke oder Funktionsanrufe. 5. Switch erlaubt die Angabe eines Rückgabewerts, der als Default verwendet wird, wenn keine andere Situation in der Struktur ausgeführt wird.
Die Schalter sind in zwei Formen unterteilt, und wir werden ein Beispiel für ein Beispiel betrachten, um zu verstehen, wie sie verwendet werden.
1 mit einem Ausdruckswitch
Ein Beispiel:
// input.string: defval, title, options, tooltip
func = input.string("EMA", title="指标名称", tooltip="选择要使用的指标函数名称", options=["EMA", "SMA", "RMA", "WMA"])
// input.int: defval, title, options, tooltip
// param1 = input.int(10, title="周期参数")
fastPeriod = input.int(10, title="快线周期参数", options=[5, 10, 20])
slowPeriod = input.int(20, title="慢线周期参数", options=[20, 25, 30])
data = input(close, title="数据", tooltip="选择使用收盘价、开盘价、最高价...")
fastColor = color.red
slowColor = color.red
[fast, slow] = switch func
"EMA" =>
fastLine = ta.ema(data, fastPeriod)
slowLine = ta.ema(data, slowPeriod)
fastColor := color.red
slowColor := color.red
[fastLine, slowLine]
"SMA" =>
fastLine = ta.sma(data, fastPeriod)
slowLine = ta.sma(data, slowPeriod)
fastColor := color.green
slowColor := color.green
[fastLine, slowLine]
"RMA" =>
fastLine = ta.rma(data, fastPeriod)
slowLine = ta.rma(data, slowPeriod)
fastColor := color.blue
slowColor := color.blue
[fastLine, slowLine]
=>
runtime.error("error")
plot(fast, title="fast" + fastPeriod, color=fastColor, overlay=true)
plot(slow, title="slow" + slowPeriod, color=slowColor, overlay=true)
Wir haben die Input-Funktion gelernt, und wir lernen hier zwei ähnliche Funktionen:input.string
、input.int
Die Funktion.input.string
Das ist ein sehr schwieriges Problem, aber es gibt viele Möglichkeiten.input.int
Die Funktion wird verwendet, um einen ganzen Wert zurückzugeben.options
Die Verwendung von Parameternoptions
Die Parameter können in eine Array von Optionswerten übertragen werden.options=["EMA", "SMA", "RMA", "WMA"]
undoptions=[5, 10, 20]
(Beachten Sie, dass einer der String-Typen und der andere der Zahlen-Typen ist). So müssen die Kontrollen in der Schaltfläche keine spezifischen Werte mehr eingegeben werden, sondern werden zu einem Dropdown-Box, in dem die in den Options-Parametern bereitgestellten Optionen ausgewählt werden.
Der Wert der Variable func ist eine String, die als Ausdruck der Variable func verwendet wird, um zu bestimmen, welcher Branch in der ausgeführten Switch ausgeführt wird. Wenn die Variable func nicht mit den Ausdrücken auf einem der Branchen in der Switch übereinstimmt, wird der Standard-Branch-Block ausgeführt, der ausgeführt wird.runtime.error("error")
Die Funktion führt dazu, dass die Strategie abweichend stoppt.
In unserem Testcode oben haben wir nach der letzten Zeile des Runtime.error des Standard-Branch-Code-Blocks von Switch keinen Code wie [na, na] hinzugefügt, um einen kompatiblen Wert zurückzugeben, der in der Handelsansicht berücksichtigt werden muss, wenn der Typ nicht übereinstimmt.
strategy("test", overlay=true)
x = if close > open
close
else
"open"
plotchar(true, title="x", char=str.tostring(x), location=location.abovebar, color=color.red)
In der FMZ werden keine Fehler gemeldet, in der Trading View werden Fehler gemeldet.
2 gibt es nicht.switch
Wir werden sehen.switch
Eine andere Art der Verwendung ist, dass sie nicht mit einer expressiven Schrift geschrieben wird.
up = close > open // up = close < open
down = close < open
var upOfCount = 0
var downOfCount = 0
msgColor = switch
up =>
upOfCount += 1
color.green
down =>
downOfCount += 1
color.red
plotchar(up, title="up", char=str.tostring(upOfCount), location=location.abovebar, color=msgColor, overlay=true)
plotchar(down, title="down", char=str.tostring(downOfCount), location=location.belowbar, color=msgColor, overlay=true)
In den Test-Code-Beispielen kann man sehen, dass Switch den lokalen Codeblock mit der Ausführungsbedingung für den Branch als wahr anpasst. Im Allgemeinen müssen sich die Branchbedingungen nach den Switch-Statements gegenseitig widersprechen. Das heißt, in diesem Beispiel können up und down nicht gleichzeitig wahr sein.up = close > open // up = close < open
Statt der in den Anmerkungen enthaltenen Inhalte, überprüfen Sie die Ergebnisse. Sie werden feststellen, dass der Switch-Branch nur den ersten Branch ausführen kann. Sie sollten außerdem darauf achten, dass Funktionsanrufe nicht in den Branchen des Switches geschrieben werden, da Funktionen nicht an jeder BAR aufgerufen werden können, was zu Datenrechenproblemen führen kann.switch
In diesem Fall ist der Exekutivzweig festgelegt und wird nicht geändert, während die Strategie ausgeführt wird.)
返回值 = for 计数 = 起始计数 to 最终计数 by 步长
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
Die Verwendung der For-Sätze ist sehr einfach. Die For-Lippe kann einen Wert (oder mehrere Werte in der Form von [a, b, c]) zurückgeben. Wie in der Pseudo-Code oben, werden Variablen an die Position "Rückgabewert" zugewiesen. Nach der For-Sprache folgt eine "Zählung" -Variable, die zur Steuerung der Anzahl der Zyklen verwendet wird, andere Werte zitiert, usw. Die "Zählung" -Variable wird vor Beginn des Zyklus als "Anfängliche Zählung" bewertet und dann nach der "Zunahme" -Einstellung weitergegeben.
für den Kreislauf verwendetbreak
Schlüsselwort: Wenn ausgeführtbreak
Nach dem Satz stoppt der Kreislauf.
für den Kreislauf verwendetcontinue
Schlüsselwort: Wenn ausgeführtcontinue
Nach dem Satz ignoriert der Kreislauf.continue
Nachfolgender Code, der direkt die nächste Runde ausführt. Der For-Satz gibt den Wert zurück, der bei der letzten Runde ausgeführt wurde. Wenn kein Code ausgeführt wurde, gibt er einen Nullwert zurück.
Hier ist ein einfaches Beispiel:
ret = for i = 0 to 10 // 可以增加by关键字修改步长,暂时FMZ不支持 i = 10 to 0 这样的反向循环
// 可以增加条件设置,使用continue跳过,break跳出
runtime.log("i:", i)
i // 如果这行不写,就返回空值,因为没有可返回的变量
runtime.log("ret:", ret)
runtime.error("stop")
for ... in
Es gibt zwei Arten von Aussagen, die mit folgenden Pseudo-Codes beschrieben werden können:
返回值 = for 数组元素 in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
返回值 = for [索引变量, 索引变量对应的数组元素] in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
Der Hauptunterschied zwischen den beiden Formen ist der Inhalt, der nach dem Schlüsselwort "for" folgt. Die eine ist die Verwendung einer Variable als Referenz für ein Arrayelement. Die andere ist die Verwendung einer Struktur, die eine Array von Variablen enthält, die eine Index-Variable, ein Arrayelement enthält.
testArray = array.from(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
for ele in testArray // 修改成 [i, ele]的形式:for [i, ele] in testArray , runtime.log("ele:", ele, ", i:", i)
runtime.log("ele:", ele)
runtime.error("stop")
Wenn Sie ein Index benötigen, verwenden Sie es.for [i, ele] in testArray
Ich bin ein guter Mann.
für Kreislaufanwendungen
Wenn man einige Kreislauf-Logik-Rechnungen mit den eingebauten Funktionen der Sprache Pine durchführen kann, kann man sie direkt mit Kreislaufstrukturen schreiben oder sie mit eingebauten Funktionen bearbeiten. Hier sind zwei Beispiele.
1 ist der berechnete Mittelwert.
Bei der Entwicklung von Kreislaufstrukturen:
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
sum = 0
for ele in a
sum += ele
avg = sum / length
plot(avg, title="avg", overlay=true)
In diesem Beispiel wird die For-Rundsummierung verwendet, um dann den Durchschnittswert zu berechnen.
Gleichlinien direkt mit der eingebauten Funktion berechnen:
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Benutzen Sie die eingebauten Funktionen direktta.sma
Die Berechnung der Gleichlinienindikatoren ist offensichtlich einfacher als die Berechnung der Gleichlinien mit Hilfe der eingebauten Funktion.
Zwei, zwei und drei.
Das kann man mit dem obigen Beispiel verdeutlichen.
Bei der Entwicklung von Kreislaufstrukturen:
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
sum = 0
for ele in a
sum += ele
avg = sum / length
plot(avg, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Für die Berechnung aller Elemente einer Array kann ein Loop verwendet werden, der auch mit einer eingebauten Funktion verarbeitet werden kannarray.sum
Ich bin nicht derjenige.
Berechnen Sie die Summe direkt mit der eingebauten Funktion:
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
plot(array.sum(a) / length, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Sie können sehen, dass die berechneten Daten vollständig übereinstimmen.
Wenn man diese Aufgaben mit eingebauten Funktionen erledigen kann, warum sollte man dann eine Schleife entwerfen? 1. Einige Operationen für Arrays, Berechnung. 2. Rückblick auf die Geschichte, z. B. um herauszufinden, wie viel früherer Höhepunkte höher sind als die Höhepunkte der aktuellen BAR. Da die Höhepunkte der aktuellen BAR nur auf der BAR bekannt sind, auf der das Skript ausgeführt wird, ist eine Schleife erforderlich, um rechtzeitig zurückzukehren und die vergangenen BAR zu analysieren. 3. Eine eingebaute Funktion mit der Sprache Pine kann die Berechnung der Vergangenheit BAR nicht abschließen.
while
Die Aussage lässt den Code für den Loop-Teil laufen, bis die Beurteilungsvoraussetzung in der while-Struktur falsch ist.
返回值 = while 判断条件
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
Die anderen Regeln von while sind ähnlich wie bei der For-Schleife. Die letzte Zeile des lokalen Codeblocks des Schleiers ist ein Rückgabewert, der mehrere Werte zurückgeben kann.
Ich möchte Ihnen noch ein Beispiel von einer Gleichlinie zeigen:
length = 10
sma(data, length) =>
i = 0
sum = 0
while i < 10
sum += data[i]
i += 1
sum / length
plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Man kann sehen, dass die Verwendung von while Loops auch sehr einfach ist, und man kann auch einige Rechenlogiken entwerfen, die nicht durch eine eingebaute Funktion ersetzt werden können, wie z.B. die Berechnung von Schritten:
counter = 5
fact = 1
ret = while counter > 0
fact := fact * counter
counter := counter - 1
fact
plot(ret, title="ret") // ret = 5 * 4 * 3 * 2 * 1
Die Definition von Arrays in der Pine-Sprache ist ähnlich wie in anderen Programmiersprachen. Die Arrays in der Pine-Sprache sind eindimensionale Arrays. Sie werden häufig verwendet, um eine Reihe von Daten zu speichern. Arrays, in denen einzelne Daten gespeichert werden, werden als Elemente der Array bezeichnet. Diese Elemente können von folgenden Typen sein: ganzt, floppy, String, Farbwert, Booleinhalt.[]
Es ist notwendig, sie zu nutzen.array.get()
undarray.set()
Die Indexfolge der Elemente in einer Array ist 0 für das erste Element und 1 für das nächste Element.
Wir zeigen es mit einem einfachen Code:
var a = array.from(0)
if bar_index == 0
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1])
else if bar_index == 1
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1])
else if bar_index == 2
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2])
else if bar_index == 3
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2], ", 向前数3根BAR上的a,即a[3]值:", a[3])
else if bar_index == 4
// 使用array.get 按索引获取元素,使用array.set按索引修改元素
runtime.log("数组修改前:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
array.set(a, 1, 999)
runtime.log("数组修改后:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
Nutzungarray<int> a
、float[] b
Eine erklärte Array oder nur eine erklärte Variable kann eine Assignierung von Arrays sein, z. B.:
array<int> a = array.new(3, bar_index)
float[] b = array.new(3, close)
c = array.from("hello", "fmz", "!")
runtime.log("a:", a)
runtime.log("b:", b)
runtime.log("c:", c)
runtime.error("stop")
Allgemeine Verwendung für die Initiierung von Arrayvariablenarray.new
undarray.from
函数。Pine语言中还有很多和类型相关的与array.new类似的函数:array.new_int()
、array.new_bool()
、array.new_color()
、array.new_string()
Und so weiter.
Das Schlüsselwort var kann auch mit dem Deklarationsmodell der Array funktionieren, wobei die Array mit der Erklärung des Schlüsselworts var nur an der ersten BAR initialiert wird.
var a = array.from(0)
b = array.from(0)
if bar_index == 1
array.push(a, bar_index)
array.push(b, bar_index)
else if bar_index == 2
array.push(a, bar_index)
array.push(b, bar_index)
else if barstate.islast
runtime.log("a:", a)
runtime.log("b:", b)
runtime.error("stop")
Man kann sehen, dass die Veränderungen der a-Array kontinuierlich festgelegt werden und nicht neu platziert werden. Die b-Array wird an jedem BAR initialiert.barstate.islast
Für die Echtzeit-Drucke bleibt nur noch ein Element, der Wert 0//.
Mit array.get erhalten Sie Elemente, für die eine bestimmte Indexposition in einer Array festgelegt wurde, und mit array.set ändern Sie Elemente, für die eine bestimmte Indexposition in einer Array festgelegt wurde.
Der erste Parameter von array.get ist die zu bearbeitende Matrix, der zweite Parameter ist der angegebene Index. Der erste Parameter von array.set ist das zu bearbeitende Array, der zweite der angegebene Index und der dritte das zu schreibende Element.
Das kann man anhand eines einfachen Beispiels erklären:
lookbackInput = input.int(100)
FILL_COLOR = color.green
var fillColors = array.new(5)
if barstate.isfirst
array.set(fillColors, 0, color.new(FILL_COLOR, 70))
array.set(fillColors, 1, color.new(FILL_COLOR, 75))
array.set(fillColors, 2, color.new(FILL_COLOR, 80))
array.set(fillColors, 3, color.new(FILL_COLOR, 85))
array.set(fillColors, 4, color.new(FILL_COLOR, 90))
lastHiBar = - ta.highestbars(high, lookbackInput)
fillNo = math.min(lastHiBar / (lookbackInput / 5), 4)
bgcolor(array.get(fillColors, int(fillNo)), overlay=true)
plot(lastHiBar, title="lastHiBar")
plot(fillNo, title="fillNo")
Das Beispiel initialiert die Grundfarbe Grün, erklärt und initialiert eine Array, die verwendet wird, um Farben zu speichern, und gibt dann den Farbwerten eine andere Transparenz an (die Funktion color.new verwendet). Die Farbstufe wird berechnet, indem man den maximalen Abstand des aktuellen BAR-Highs in 100 Sichtzyklen berechnet. Je näher der Maximalwert des Highs in den letzten 100 Sichtzyklen ist, desto höher ist der entsprechende Farbwert (die Transparenz ist niedriger). Viele ähnliche Strategien geben in dieser Weise die Stufe des Preises in den aktuellen N Sichtzyklen an.
Wie man eine Array durchläuft, kann man mit den For/for in/while-Sätzen machen, die wir vorher gelernt haben.
a = array.from(1, 2, 3, 4, 5, 6)
for i = 0 to (array.size(a) == 0 ? na : array.size(a) - 1)
array.set(a, i, i)
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)
i = 0
while i < array.size(a)
array.set(a, i, i)
i += 1
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)
for [i, ele] in a
array.set(a, i, i)
runtime.log(a)
runtime.error("stop")
Die drei Wege führen zu den gleichen Ergebnissen.
Arrays können sowohl im globalen Bereich des Skripts als auch im lokalen Bereich der Funktion oder der if-Branche deklariert werden
Für die Verwendung von Elementen in einer Array ist die folgende Methode gleichwertig. Wir können anhand des folgenden Beispiels sehen, dass zwei Gruppen von Linien auf einem Diagramm gezeichnet werden, in denen jede Gruppe zwei Linien hat und die beiden Linien in jeder Gruppe genau die gleichen Werte haben.
a = array.new_float(1)
array.set(a, 0, close)
closeA1 = array.get(a, 0)[1]
closeB1 = close[1]
plot(closeA1, "closeA1", color.red, 6)
plot(closeB1, "closeB1", color.black, 2)
ma1 = ta.sma(array.get(a, 0), 20)
ma2 = ta.sma(close, 20)
plot(ma1, "ma1", color.aqua, 6)
plot(ma2, "ma2", color.black, 2)
1. Die Funktion, die mit der Erhöhung der Arrays verbunden ist:
array.unshift()
、array.insert()
、array.push()
。
2. Funktionen für die Löschung von Arrays:
array.remove()
、array.shift()
、array.pop()
、array.clear()
。
Wir testen die Ergänzungs- und Entfernungselementen dieser Arrays mit den folgenden Beispielen.
a = array.from("A", "B", "C")
ret = array.unshift(a, "X")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.insert(a, 1, "Y")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.push(a, "D")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.remove(a, 2)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.shift(a)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.pop(a)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.clear(a)
runtime.log("数组a:", a, ", ret:", ret)
runtime.error("stop")
Hinzufügen und Entfernen von Anwendungen: Arrays als Schlange
Mit Arrays und einigen Array-Ergänzungs- und Entfernungsfunktionen können wir eine Datenstruktur erstellen, die als "Strecke" bezeichnet wird.
Eine Warteschlange ist eine Struktur, die häufig im Programmiersektor verwendet wird.
Ein Element, das zuerst in die Warteschlange kommt, kommt zuerst aus der Warteschlange.
Dies stellt sicher, dass die Daten, die in der Warteschlange vorhanden sind, die neuesten Daten sind und dass die Warteschlange nicht unendlich lang ist (Kode mit unendlicher Warteschlange kann nur um Mittag geschrieben werden, da Frühstück und Nachmittag Probleme verursachen).
In dem folgenden Beispiel verwenden wir eine Queue-Struktur, um den Preis pro Ticks zu erfassen, den gleitenden Durchschnitt der Ticks zu berechnen und dann mit dem gleitenden Durchschnitt der K-Linien-Ebenen in 1 Minute zu vergleichen.
strategy("test", overlay=true)
varip a = array.new_float(0)
var length = 10
if not barstate.ishistory
array.push(a, close)
if array.size(a) > length
array.shift(a)
sum = 0.0
for [index, ele] in a
sum += ele
avgPrice = array.size(a) == length ? sum / length : na
plot(avgPrice, title="avgPrice")
plot(ta.sma(close, length), title="ta.sma")
Beachten Sie, dass wir beim Deklarieren der Array a den Deklarierungsmodus angegeben haben, mit dem Schlüsselwortvarip
Hierbei wird jede Preisänderung in einer Matrix aufgezeichnet.
Berechnen Sie die Funktionen:
array.avg()
Die durchschnittlichen Werte aller Elemente in einer Array.array.min()
Das kleinste Element in einer Array.array.max()
Das ist das größte Element in der Array.array.stdev()
Die Standarddifferenz aller Elemente in einer Arithmetie.array.sum()
Die Summe aller Elemente in einer Array.
Funktionen, die mit der Bedienung verbunden sind:array.concat()
Zwei Arrays zu kombinieren oder zu verbinden.array.copy()
Das ist ein sehr schwieriges Problem.array.join
Alle Elemente in einer Array werden zu einer String verbunden.array.sort()
Sie werden in Aufstiegs- oder Abstiegsreihenfolge sortiert.array.reverse()
Die Umkehrung der Matrix.array.slice()
Die Array wird zerschnitten.array.includes()
Das Urteil über die Elemente.array.indexof()
Geben Sie den Index, in dem der eingegebene Wert zuerst erschien. Wenn dieser nicht gefunden wird, gibt er -1 zurück.array.lastindexof()
Finden Sie den Wert, der zuletzt erschienen ist.
Testbeispiele für die Berechnung der relevanten Funktionen in Arithmetik:
a = array.from(3, 2, 1, 4, 5, 6, 7, 8, 9)
runtime.log("数组a的算数平均:", array.avg(a))
runtime.log("数组a中的最小元素:", array.min(a))
runtime.log("数组a中的最大元素:", array.max(a))
runtime.log("数组a中的标准差:", array.stdev(a))
runtime.log("数组a的所有元素总和:", array.sum(a))
runtime.error("stop")
Dies sind die am häufigsten verwendeten Arithmetik-Funktionen.
Beispiele für die Handhabung der entsprechenden Funktionen:
a = array.from(1, 2, 3, 4, 5, 6)
b = array.from(11, 2, 13, 4, 15, 6)
runtime.log("数组a:", a, ", 数组b:", b)
runtime.log("数组a,数组b连接在一起:", array.concat(a, b))
c = array.copy(b)
runtime.log("复制一个数组b,赋值给变量c,变量c:", c)
runtime.log("使用array.join处理数组c,给每个元素中间增加符号+,连接所有元素结果为字符串:", array.join(c, "+"))
runtime.log("排序数组b,按从小到大顺序,使用参数order.ascending:", array.sort(b, order.ascending)) // array.sort函数修改原数组
runtime.log("排序数组b,按从大到小顺序,使用参数order.descending:", array.sort(b, order.descending)) // array.sort函数修改原数组
runtime.log("数组a:", a, ", 数组b:", b)
array.reverse(a) // 此函数修改原数组
runtime.log("反转数组a中的所有元素顺序,反转之后数组a为:", a)
runtime.log("截取数组a,索引0 ~ 索引3,遵循左闭右开区间规则:", array.slice(a, 0, 3))
runtime.log("在数组b中搜索元素11:", array.includes(b, 11))
runtime.log("在数组a中搜索元素100:", array.includes(a, 100))
runtime.log("将数组a和数组b连接,搜索其中第一次出现元素2的索引位置:", array.indexof(array.concat(a, b), 2), " , 参考观察 array.concat(a, b):", array.concat(a, b))
runtime.log("将数组a和数组b连接,搜索其中最后一次出现元素6的索引位置:", array.lastindexof(array.concat(a, b), 6), " , 参考观察 array.concat(a, b):", array.concat(a, b))
runtime.error("stop")
Die Pine-Sprache kann benutzerdefinierte Funktionen entwerfen, die im Allgemeinen folgende Regeln haben:
1. Alle Funktionen sind im globalen Rahmen des Skripts definiert. Eine Funktion kann nicht in einer anderen Funktion deklariert werden.
2. Die Funktion darf sich nicht in ihrem Code selbst aufrufen.
3, grundsätzlich alle PINE-Sprachen haben eine eingebaute Grafikfunktionbarcolor()、 fill()、 hline()、plot()、 plotbar()、 plotcandle()
) kann nicht in einer benutzerdefinierten Funktion aufgerufen werden.
4. Die Funktion kann als Einzelzeile oder mehrere Zeilen geschrieben werden. Der Rückgabewert des letzten Satzes ist der Rückgabewert der aktuellen Funktion, die die Form eines Elements zurückgibt.
In früheren Tutorials haben wir auch mehrmals benutzt, wie z.B. die Einzeilinie:
barIsUp() => close > open
Die Funktion gibt an, ob die aktuelle BAR die Sonnenstrahlung ist.
Es wurde als mehrstrichige benutzerdefinierte Funktionen konzipiert:
sma(data, length) =>
i = 0
sum = 0
while i < 10
sum += data[i]
i += 1
sum / length
plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Eine Funktion, die wir selbst mit einer benutzerdefinierten Funktion realisiert haben.
Außerdem kann man ein Beispiel für eine benutzerdefinierte Funktion mit zwei Variablen zurückgeben:
twoEMA(data, fastPeriod, slowPeriod) =>
fast = ta.ema(data, fastPeriod)
slow = ta.ema(data, slowPeriod)
[fast, slow]
[ema10, ema20] = twoEMA(close, 10, 20)
plot(ema10, title="ema10", overlay=true)
plot(ema20, title="ema20", overlay=true)
Eine Funktion kann eine schnelle Linie, eine langsame Linie und zwei EMA-Gleichlinien berechnen.
Die eingebauten Funktionen können sehr einfach inFMZ PINE Script DokumentationIch habe eine Frage gestellt.
Die Pine-Funktion ist hier aufgeführt:
1, eine String-Verarbeitung.str.
Die Serie.
2, die Farbwertverarbeitungcolor.
Die Serie.
3. Die Parameter-Eingabefunktioninput.
Die Serie.
4. Indikatorberechnungsfunktionta.
Die Serie.
5. Die Grafikfunktionplot.
Die Serie.
6. Arithmetikverarbeitungsfunktionarray.
Die Serie.
7. Transaktionsfunktionenstrategy.
Die Serie.
8. Mathematische Funktionenmath.
Die Serie.
9, andere Funktionen ((Zeitverarbeitung, Non-Plot-Serien-Grafikfunktionen,request.
Sie werden von der Funktion "Typ-Processing" (Typ-Verarbeitung) abgerufen.
strategy.
Serie-Funktionen sind Funktionen, die wir häufig in unserer Design-Strategie verwenden, und sie sind eng mit der Strategie verbunden, um Transaktionen auszuführen, wenn sie ausgeführt werden.
1、strategy.entry
strategy.entry
Die Funktion ist eine untergeordnete Funktion, die bei der Erstellung von Strategien wichtiger ist.id
, direction
, qty
, when
Und so weiter.
Parameter:
id
: kann verstanden werden, um einen Namen für eine Handelsposition zu verwenden.direction
: wenn die Bestellrichtung mehr (kaufen) ist, wird die Parameter übertragenstrategy.long
Diese eingebaute Variable wird übertragen, wenn man sie leert.strategy.short
Diese Variable.qty
: Bestimmt die Anzahl der Bestellungen, wenn dieser Parameter nicht übermittelt wird, wird die Anzahl der Bestellungen standardmäßig verwendet.when
: Ausführungsbedingungen, die angegeben werden können, um zu steuern, ob die aktuelle Unterordnungsoperation ausgelöst wird.limit
Es gibt eine Reihe von Möglichkeiten, wie Sie Ihre Bestellung anbieten können.stop
Das ist ein großes Problem.strategy.entry
Spezifische Funktionsdetailsstrategy
Die Parameter-Einstellungen bei Funktionsaufrufen können auch durch"Pine-Language Exchange-Library-Modellparameter"Für weitere Details zu den Transaktionen, die durch die Einstellung von Kontrollen und die Parameter der Template der Transaktionslibrary in der Sprache Pine gesteuert werden, siehe Dokumentation unter dem Link.
Hier ist der Schwerpunkt.strategy
Wir haben eine Funktion.pyramiding
、default_qty_value
Parameter. Test mit folgendem Code:
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)
ema10 = ta.ema(close, 10)
findOrderIdx(idx) =>
if strategy.opentrades == 0
false
else
ret = false
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := true
break
ret
if not findOrderIdx("long1")
strategy.entry("long1", strategy.long)
if not findOrderIdx("long2")
strategy.entry("long2", strategy.long, 0.2, when = close > ema10)
if not findOrderIdx("long3")
strategy.entry("long3", strategy.long, 0.2, limit = low[1])
strategy.entry("long3", strategy.long, 0.3, limit = low[1])
if not findOrderIdx("long4")
strategy.entry("long4", strategy.long, 0.2)
plot(ema10, title="ema10", color=color.red)
Der Code beginnt/*backtest ... */
Der Paketanteil ist für die Wiederholung eingestellt, um Informationen wie den Zeitpunkt der Wiederholung zu erfassen, um Debugging zu erleichtern, nicht um Strategiecode zu erstellen.
Der Code:strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)
Wenn wir diepyramiding
Wenn die Parameter 3 sind, dann haben wir die Möglichkeit, dass wir in der gleichen Richtung bis zu drei Mal handeln.strategy.entry
Eine der folgenden Operationen wurde nicht ausgeführt.default_qty_value
Die Parameter sind 0.1, also ist die ID-Kennzeichnung für das Dinglong 1 Ding.strategy.entry
Die Unterordnungszahl für die Unterordnungsoperation ist standardmäßig auf 0.1 festgelegt.strategy.entry
Die Funktion, auf die wir zugeschrieben haben, wenn wir sie aufrufen.direction
Gleichstrategy.long
Das bedeutet, dass man bei der Nachprüfung bezahlt wird.
Achten Sie auf den Code.strategy.entry("long3", ...
Die folgende Operation wird zweimal aufgerufen, für die gleiche ID: strategy.entry
Der Nachbestellvorgang wurde nicht abgewickelt, zweiter Aufrufstrategy.entry
Die Funktion ändert die ID der Bestellung (die Daten, die bei der Rückprüfung angezeigt werden, zeigen auch, dass die Bestellmenge für diese Limit-Bestellung für 0.3 geändert wurde).strategy.entry
Wenn die Funktion eine Bestellung aufgibt, werden alle Bestellpositionen auf der ID-Length-3-Length angesammelt.
2、strategy.close
strategy.close
Die Funktion wird verwendet, um die Eintrittspositionen für die Identifikations-ID der Eintrittspositionen zu bestimmen. Die Hauptparameter sind:id
,when
,qty
,qty_percent
。
Parameter:
id
Wir verwenden das Login-ID, das für die Abrechnung benötigt wird.strategy.entry
Die ID, die bei Eintritt der Einzelfunktion angegeben wird.when
Die Bedingungen für die Umsetzung.qty
Die Zahl der Anleihen.qty_percent
Der Anteil an der Ausgleichsquote.Hier ist ein Beispiel, wie man diese Funktion verwenden kann:
In der Code/*backtest ... */
是FMZ.COM国际站回测时的配置信息,可以删掉,设置自己需要测试的市场、品种、时间范围等信息。
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("close Demo", pyramiding=3)
var enableStop = false
if enableStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.2)
if strategy.opentrades >= 3
strategy.close("long1") // 多个入场订单,不指定qty参数,全部平仓
// strategy.close() // 不指定id参数,会平掉当前的持仓
// strategy.close("long2") // 如果指定一个不存在的id则什么都不操作
// strategy.close("long1", qty=0.15) // 指定qty参数平仓
// strategy.close("long1", qty_percent=50) // qty_percent设置50即为平掉long1标识仓位的50%持仓
// strategy.close("long1", qty_percent=80, when=close<open) // 指定when参数,修改为close>open就不触发了
enableStop := true
Die Teststrategie zeigt, dass Sie drei Mal in Folge mehrere Einträge machen, die Eintrittskennzeichen sind jeweils 1 strategy.close
Verschiedene Ergebnisse, die bei der Einstellung verschiedener Parameter der Funktion wiedergefunden werden.strategy.close
Diese Funktion hat keine Parameter, um den Preis für die Auflösung zu bestimmen. Die Funktion wird hauptsächlich für die sofortige Auflösung zum aktuellen Marktpreis verwendet.
3、strategy.close_all
strategy.close_all
Die Funktion wird verwendet, um alle aktuellen Positionen auszugleichen, da die Pine-Skripte nur in einer Richtung positionieren können, d. h. wenn ein Signal ausgelöst wird, der der gegenwärtigen Positionsrichtung entgegengesetzt ist, wird der aktuelle Positionswert ausgeglichen und die Position entsprechend ausgelöst.strategy.close_all
Wenn sie aufgerufen werden, werden alle Haltungen in der aktuellen Richtung ausgeglichen.strategy.close_all
Die Hauptparameter der Funktion sind:when
。
Parameter:
when
Die Bedingungen für die Umsetzung.Wir haben ein Beispiel verwendet, um zu beobachten:
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("closeAll Demo")
var enableStop = false
if enableStop
runtime.error("stop")
strategy.entry("long", strategy.long, 0.2, when=strategy.position_size==0 and close>open)
strategy.entry("short", strategy.short, 0.3, when=strategy.position_size>0 and close<open)
if strategy.position_size < 0
strategy.close_all()
enableStop := true
Wenn wir den Testcode anfangen, ist die Lagermenge 0 (d.h.strategy.position_size==0
Wenn die Definition von When erfüllt ist, wird die Definition von When nur dann ausgeführt, wenn die Definition von When erfüllt ist.strategy.entry
Eintrittsfunktion.strategy.position_size
Die Eintrittsfunktion für die "ID" ist größer als 0 und kann nur dann ausgeführt werden, wenn die "ID" für die "ID" für die "ID" ist. Da die Position derzeit mehrfach gehalten wird, wird das "STOP"-Rückwärtssignal angezeigt, was dazu führt, dass die Position mehrfach gehalten wird.strategy.position_size < 0
Wenn Sie eine Position halten, die sich in der Richtung der aktuellen Position befindet, werden alle Positionen ausgeglichen.enableStop := true
◦ Die Aktivierung der Aktion unterbrechen, damit die Logs besser beobachtet werden können.
Sie können es finden.strategy.close_all
Diese Funktion hat keine Parameter, um den Preis für die Auflösung zu bestimmen. Die Funktion wird hauptsächlich für die sofortige Auflösung zum aktuellen Marktpreis verwendet.
4、strategy.exit
strategy.exit
Die Funktion wird für die Eintritts-Platzierung verwendet.strategy.close
undstrategy.close_all
Die Funktion wird sofort zum aktuellen Marktpreis ausgeglichen.strategy.exit
Die Funktion schlägt nach den Parameter-Einstellungen aus.
Parameter:
id
: Order-ID für die aktuelle Bilanzierungsbedingungen.from_entry
: wird verwendet, um die Login-ID für die Ausgleichsoperation anzugeben.qty
Die Zahl der Anleihen.qty_percent
: Flachgewichtsprozentsatz, Bereich: 0 ~ 100.profit
Das Ziel ist: Gewinnziele, in Punkten angegeben.loss
Das Ziel des Stopps wird in Punkten angegeben.limit
Der Profitziel wird mit einem Preis angegeben.stop
Das Ziel ist: Stopp-Loss, Preis angegeben.when
Die Bedingungen für die Umsetzung.Verwenden Sie eine Teststrategie, um die Verwendung der Parameter zu verstehen.
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("strategy.exit Demo", pyramiding=3)
varip isExit = false
findOrderIdx(idx) =>
ret = -1
if strategy.opentrades == 0
ret
else
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := i
break
ret
strategy.entry("long1", strategy.long, 0.1, limit=1, when=findOrderIdx("long1") < 0)
strategy.entry("long2", strategy.long, 0.2, when=findOrderIdx("long2") < 0)
strategy.entry("long3", strategy.long, 0.3, when=findOrderIdx("long3") < 0)
if not isExit and strategy.opentrades > 0
// strategy.exit("exitAll") // 如果仅仅指定一个id参数,则该退场订单无效,参数profit, limit, loss, stop等出场条件也至少需要设置一个,否则也无效
strategy.exit("exit1", "long1", profit=50) // 由于long1入场订单没有成交,因此ID为exit1的出场订单也处于暂待状态,直到对应的入场订单成交才会放置exit1
strategy.exit("exit2", "long2", qty=0.1, profit=100) // 指定参数qty,平掉ID为long2的持仓中0.1个持仓
strategy.exit("exit3", "long3", qty_percent=50, limit=strategy.opentrades.entry_price(findOrderIdx("long3")) + 1000) // 指定参数qty_percent,平掉ID为long3的持仓中50%的持仓
isExit := true
if bar_index == 0
runtime.log("每点价格为:", syminfo.mintick) // 每点价格和Pine语言模板参数上「定价货币精度」参数设置有关
Die Teststrategie beginnt mit der Ausführung von 3 Eintrittsvorgängen, die mit einem Echtzeit-Preismodell-Rücktest durchgeführt werden.strategy.entry
Funktion), die auf "long1" eingestellt istlimit
Parameter, der Preis für die Auflage 1 macht sie nicht möglich; dann testen Sie die Bedingungen für den Ausgang der Funktionstrategy.exit
Hierbei wird ein Stopp durch Punktzahl, ein Stopp durch Preis, ein Steigerung der Anzahl der Positionen und ein Steigerung des Prozentsatzes verwendet.strategy.exit
Die Funktion hat auch noch kompliziertere Tracking-Stopp-Parameter:trail_price
、trail_points
、trail_offset
Sie können auch in diesem Beispiel testen, um zu lernen, wie sie verwendet werden.
5、strategy.cancel
strategy.cancel
Funktionen, die verwendet werden, um alle Vorhang-Befehle zu löschen.strategy.order
, strategy.entry
, strategy.exit
Sie können eine Anmeldedatenbank erstellen. Die Hauptparameter der Funktion sind:id
、when
。
Parameter:
id
Sie müssen sich nicht an die Anmeldung beteiligen.when
Die Bedingungen für die Umsetzung.Diese Funktion ist sehr verständlich, weil sie für die Abschaffung von nicht-transformierten Login-Befehlen verwendet wird.
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("strategy.cancel Demo", pyramiding=3)
var isStop = false
if isStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)
if not barstate.ishistory and close < open
strategy.cancel("long1")
strategy.cancel("long2")
strategy.cancel("long3")
isStop := true
6、strategy.cancel_all
strategy.cancel_all
Funktionen undstrategy.cancel
Funktionen ähnlich wie ‹ab/abschalten aller Vorhangbefehle› können angegeben werdenwhen
Parameter.
Parameter:
when
Die Bedingungen für die Umsetzung./*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("strategy.cancel Demo", pyramiding=3)
var isStop = false
if isStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)
if not barstate.ishistory and close < open
strategy.cancel_all()
isStop := true
7、strategy.order
strategy.order
Funktionen, Parameter-Einstellungen und so weiter sind fast identisch.strategy.entry
Einheitlich, unterscheidet sichstrategy.order
Die Funktion ist nichtstrategy
Die Funktionpyramiding
Einfluss auf die Einstellung von Parametern, ohne Einsatzbegrenzung.
Parameter:
id
: kann verstanden werden, um einen Namen für eine Handelsposition zu verwenden.direction
: wenn die Bestellrichtung mehr (kaufen) ist, wird die Parameter übertragenstrategy.long
Diese eingebaute Variable wird übertragen, wenn man sie leert.strategy.short
Diese Variable.qty
: Bestimmt die Anzahl der Bestellungen, wenn dieser Parameter nicht übermittelt wird, wird die Anzahl der Bestellungen standardmäßig verwendet.when
: Ausführungsbedingungen, die angegeben werden können, um zu steuern, ob die aktuelle Unterordnungsoperation ausgelöst wird.limit
Es gibt eine Reihe von Möglichkeiten, wie Sie Ihre Bestellung anbieten können.stop
Das ist ein großes Problem.Wir benutzenstrategy.order
Es gibt keine Begrenzung für diese Eigenschaft.strategy.exit
Die bedingte Ausstiegsfunktion ─ Konstruieren eines Skripts, das wie eine Gittertransaktion aussieht ─ ist ein sehr einfaches Beispiel, das nur für das Lernen verwendet wird:
/*backtest
start: 2021-03-01 00:00:00
end: 2022-08-30 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["ZPrecision",0,358374]]
*/
varip beginPrice = -1
if not barstate.ishistory
if beginPrice == -1 or (math.abs(close - beginPrice) > 1000 and strategy.opentrades == 0)
beginPrice := close
for i = 0 to 20
strategy.order("buy"+i, strategy.long, 0.01, limit=beginPrice-i*200, when=(beginPrice-i*200)<close)
strategy.exit("coverBuy"+i, "buy"+i, qty=0.01, profit=200)
strategy.order("sell"+i, strategy.short, 0.01, limit=beginPrice+i*200, when=(beginPrice+i*200)>close)
strategy.exit("coverSell"+i, "sell"+i, qty=0.01, profit=200)
Die Strategien in diesem Tutorial dienen ausschließlich der Lehre von Strategien und der Konzeption von Strategien, nicht als Handlungshilfe oder Empfehlung.
strategy("supertrend", overlay=true)
[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))
plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr)
plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr)
if direction < 0
if supertrend > supertrend[2]
strategy.entry("entry long", strategy.long)
else if strategy.position_size < 0
strategy.close_all()
else if direction > 0
if supertrend < supertrend[3]
strategy.entry("entry short", strategy.short)
else if strategy.position_size > 0
strategy.close_all()
Es ist sehr einfach, eine Trendstrategie in der Sprache Pine zu schreiben. Hier entwerfen wir eine einfache Trend-Tracking-Strategie mit einem Super-Trend-Indikator.
Das ist der erste Schritt, um den Strategic Code zu verwenden.strategy
Die Funktion macht einige einfache Einstellungen:strategy("supertrend", overlay=true)
, einfach eine Strategie mit der Überschrift "Supertrend"-Tastatur eingestellt.overlay
Die Parameter sind:true
Wenn wir eine Pine-Strategie entwerfen oder ein Pine-Skript lernen, müssen wir uns zunächst die Parameter für die Strategieinterface entwerfen, und wir schauen uns die Quellen für die Supertrend-Indikator-Strategie an, die wir in früheren Kursen gelernt haben.input
Funktionen
[Supertrend, Richtung] = ta.Supertrend ((Eingabe ((5,
Faktor input.int(10,), atPeriode ))
input
Funktionsanrufe werden direkt verwendet.ta.supertrend
Die Parameter der Indikatorfunktion werden für die Berechnung der Supertendenzindikatoren verwendet.
Die Funktion setzt standardmäßig zwei Parameter-Kontrollen in der Pine-Politik-Schnittstelle ein, wie folgt:
Sie können sehen, dass der Standardwert für die Steuerunginput
Funktionen undinput
Hier ist eine Reihe von Funktionen.input.int
Diese beiden Funktionen können wir in der Strategie-Schnittstelle einstellen.ta.supertrend
Die Parameter der Funktion. Die Supertrend-Indikator-Funktion berechnet eine Preisdaten.supertrend
und eine Richtung Datendirection
Und dann benutzt man sie.plot
Funktionsdiagramme, beachten Sie, dass die Diagramme nur in der aktuellen Richtung gezeichnet werden, wenn sie in der Richtung des Supertrend-Indikators gezeichnet werden.direction
Die aktuelle Marktentwicklung ist aufwärts bei -1 Uhr.direction
Der Markt ist um 1 Uhr auf dem Abwärtstrend.plot
Beurteilen Sie, wenn Sie ein Diagramm zeichnendirection
Größer als, kleiner als 0.
Die nächsteif ... else if
Logik ist die Beurteilung der Transaktionssignale, wenn diedirection < 0
In Echtzeit zeigt, dass die aktuelle Marktlage in der oberen Phase ist, wenn die Preisdaten im Supertrend-Indikatorsupertrend
Der Preis des Supertrend-Indikators auf den ersten 2 BARs ist höher als der Preis des Supertrend-Indikators (d.h.supertrend[2],还记得历史操作符引用某个变量历史数据吧
Erinnern Sie sich daran? Wenn Sie gerade eine Position haben, werden Sie mit einem umgekehrten Einzelfunktionsanruf die vorherige Position ausgleichen und dann entsprechend der aktuellen Handelsrichtung eröffnen.supertrend > supertrend[2]
Die Bedingungen sind nicht erfüllt.strategy.position_size < 0
Das bedeutet, dass die Position des Leerstandes auch ausgelöst wird.strategy.close_all()
Die Funktion wird ausgeführt und alle Ausgleichswerte ausgeführt.
direction > 0
Das gleiche gilt für die Abwärtstrendphase, wenn mehrere Positionen ausgeglichen werden und die Bedingungen erfüllt sind.supertrend < supertrend[3]
Wenn Sie ein Blackout-Signal auslösen, warum ist das hier so eingestellt?[3]
Was ist mit den Supertrend-Index-Preisdaten auf der dritten Bar? Vielleicht ist das die Absicht des Strategisten, denn in einigen Märkten, wie z. B. im Contract-Trading-Markt, ist das Null-Risiko etwas größer als das Mehr-Risiko.
Fürta.supertrend
Der Indikator, den einige Schüler interessieren, ist, wie man den aktuellen Trend aufwärts oder abwärts beurteilt.
In der Tat kann dieser Indikator auch in Form einer benutzerdefinierten Funktion in der Sprache Pine realisiert werden:
pine_supertrend(factor, atrPeriod) =>
src = hl2
atr = ta.atr(atrPeriod)
upperBand = src + factor * atr
lowerBand = src - factor * atr
prevLowerBand = nz(lowerBand[1])
prevUpperBand = nz(upperBand[1])
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
int direction = na
float superTrend = na
prevSuperTrend = superTrend[1]
if na(atr[1])
direction := 1
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Diese benutzerdefinierte Funktion ist eine eingebaute Funktionta.supertrend
Die gleiche Algorithmus, natürlich auch die gleichen Indikatordaten.
Aus diesem Algorithmus der Custom Function können wir sehen, dass die Supertrend-Anzeige, die Pine eingebaut hat, mithl2
Die Variablen (höchste, niedrigste, addierte und durch 2 geteilte Höchst- und niedrigste Preise) werden dann mit dem Parameter atrPeriod berechnet.
Aktualisiert nach den dreifachen Ausdrücken im CodelowerBand
undupperBand
。
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
lowerBand: Unterstrecke, um zu bestimmen, ob sich der Aufwärtstrend geändert hat. upperBand: Oberstrecke, um zu bestimmen, ob sich der Abwärtstrend geändert hat. lowerBand und upperBand werden immer berechnet, nur um die aktuelle Trendrichtung zu bestimmen.
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
Hier wird festgestellt, ob der Preiswert des Supertrendens auf der letzten BARprevUpperBand
Wenn Sie sich in der Nähe von einem anderen Ort befinden, können Sie sich in der Nähe von einem anderen Ort befinden.close
Mehr alsupperBand
Der Preis wird durchbrochen, weil man glaubt, dass sich die Tendenz in diesem Moment verändert hat und sich in einen Aufwärtstrend verwandelt.direction
Die Richtungsvariablen sind auf -1 ((Obertrend)); ansonsten bleiben sie auf 1 ((Abwärtstrend)); also sehen Sie es in der Supertrend-Strategie.if direction < 0
Wenn die Signalbedingungen ausgelöst werden, dann tun Sie mehr.direction > 0
Wenn die Signalbedingungen ausgelöst werden, ist die Auslösung möglich.
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Schließlich werden die spezifischen Supertrend-Indikatoren für die Preisdaten und die Richtungsdaten nach Richtung ausgewählt.
/*backtest
start: 2021-03-01 00:00:00
end: 2022-09-08 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["v_input_1",4374],["v_input_2",3],["v_input_3",300],["ZPrecision",0,358374]]
*/
varip balance = input(50000, "balance")
varip stocks = input(0, "stocks")
maxDiffValue = input(1000, "maxDiffValue")
if balance - close * stocks > maxDiffValue and not barstate.ishistory
// more balance , open long
tradeAmount = (balance - close * stocks) / 2 / close
strategy.order("long", strategy.long, tradeAmount)
balance := balance - tradeAmount * close
stocks := stocks + tradeAmount
runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)
else if close * stocks - balance > maxDiffValue and not barstate.ishistory
// more stocks , open short
tradeAmount = (close * stocks - balance) / 2 / close
strategy.order("short", strategy.short, tradeAmount)
balance := balance + tradeAmount * close
stocks := stocks - tradeAmount
runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)
plot(balance, title="balance value(quoteCurrency)", color=color.red)
plot(stocks*close, title="stocks value(quoteCurrency)", color=color.blue)
Wir lernen weiter einige Strategien-Design-Probleme in der Pine-Sprache, und diesmal sehen wir eine dynamische Balance-Strategie.BaseCurrency
(Transaktionsart) undQuoteCurrency
Die Summe wird stets ausgeglichen. Der relative Preis eines Vermögenswerts steigt und der Wert des im Konto gehaltenen Vermögens steigt, und der Vermögenswert wird verkauft. Wenn der relative Preis eines Vermögenswerts sinkt und der Wert des im Konto gehaltenen Vermögenswert sinkt, kauft man diesen Vermögenswert. Dies ist die sogenannte dynamische Ausgleichsstrategie.
Der Nachteil dieser Strategie ist, dass sie, wie in den Rücksichtsdiagrammen zu sehen ist, in der Phase eines hohen (oder niedrigeren) Kurstrends eine größere Gewinne erzielt.
Wir haben eine Reihe von Programmen entwickelt, die in der Lage sind, unsere Kunden zu unterstützen.
Wir haben ein vereinfachtes Design verwendet, um eine Strategie zu simulieren, in der wir einebalance
(d.h. Anzahl der Quoten-Währungs-Assets) undstocks
Die Balance-Informationen. Wir lesen nicht die tatsächliche Anzahl der Vermögenswerte in den Konten, sondern verwenden nur simulierte Beträge, um die richtigen Käufe und Verkäufe zu berechnen.maxDiffValue
Der Parameter ist der Maßstab für die Ausgewogenheit.BaseCurrency
undQuoteCurrency
Die Abweichungen übersteigenmaxDiffValue
Es ist Zeit, sich auszugleichen, hochpreisige Vermögenswerte zu verkaufen, niedrige zu kaufen und die Vermögenswerte wieder auszugleichen.
Strategie-Trading-Signale müssen erst in der Echtzeit-BAR-Phase sinnvoll ausgelöst werden, so dass die strategischen Trading-Bedingungen im If-Urteil gesetzt werden.not barstate.ishistory
Und wenn man die Preise anhand der aktuellen Preise berechnet, dann sind es die Preise, die man verdient.balance
Der Wert ist überschrittenstocks
Kauf bei Wert; Verkauf umgekehrt; Aktualisierung nach der Ausführung des Transaktionssatzesbalance
undstocks
Sie werden dann auf die nächste Balance-Trigger warten.
Die oben angegebene Strategie-Rücklauf-Nachricht enthält den Preis für die Sorte, bei der die Strategie-Rücklauf-Nachricht begann, und der Preis ist 1458, also habe ich die Parameter absichtlich eingestellt.balance
Parameter für: 4374 ((1458*3)stocks
3. Das Vermögen am Anfang im Gleichgewicht zu halten.
Wir haben in früheren Kursen gelernt,strategy.exit
Die Positionsaustritt-Funktion, bei der die Tracking-Stopp-Loss-Stopp-Funktion nicht beschrieben wird.strategy.exit
Die Tracking-Stopp-Loss-Stopp-Funktion der Funktion optimiert eine Supertrend-Strategie.
Erst mal sehen wir:strategy.exit
Die Tracking-Stopp-Loss-Stopp-Parameter der Funktion:
1、trail_price
Parameter: Auslöser, der die logische Position des Tracking Stop-Loss-Bilanzordens auslöst (z.B. Preis angegeben)