Nachdem Sie die Gestaltung einer quantitativen Handelsstrategie abgeschlossen haben, wie können Sie die grundlegende Situation Ihrer Strategie kennen, wie die Logik der Strategie und die Richtung der Rendite der Strategie? Natürlich können wir nicht direkt echtes Geld verwenden, um die Strategie auf dem realen Handelsmarkt auszuführen, aber wir können historische Daten verwenden, um Ihre Strategie zu testen und die Gewinne Ihrer Strategie in den historischen Daten zu kennen.
FMZ Quant Trading Platform teilt das Backtestsystem inBot-EbeneundSimulationsstufe. Die Bot-Ebene ist, um Backtest vollständig nach den vollständigen historischen Daten; während die Simulation-Ebene Backtest erzeugttick
Die Daten basieren beide auf den realen historischen Daten, aber die Daten auf Bot-Ebene sind genauer und die Ergebnisse glaubwürdiger. Allerdings ist das Backtesting nur die Leistung der Strategie nach historischen Daten. Die historischen Daten können den zukünftigen Markt nicht vollständig repräsentieren. Der historische Markt kann sich wiederholen oder auch zum Schwarzen Schwanen führen. Daher sollten die Rücktests rational und objektiv behandelt werden.
DieSimulationsstufe Tickerzeugt die simulierteZeichendatenAuf der Grundlage der zugrunde liegenden K-Linienperiode erzeugt jede zugrunde liegende K-Linienperiode maximal 12 Backtest-Zeitpunkte.Marktwert TickDas Backtesting-Mechanismus von FMZ Quant ermöglicht es der Strategie, mehrmals auf einer einzigen K-Linie zu handeln, wodurch die Situation vermieden wird, in der der Handel nur zum Schlusskurs ausgeführt werden kann.
Beschreibung des Mechanismus des Backtestsystems
Simulationsstufe Tick DieSimulationsstufe Tickbasiert auf den zugrunde liegenden K-Liniendaten des Backtestsystems, simuliert Tick-Daten zum Backtest im Rahmen des höchsten Preises, des niedrigsten Preises, des Eröffnungspreises und des Schlusskurswerts einer gegebenen zugrunde liegenden K-Linienleiste nach einem bestimmten Algorithmus. Als Echtzeit-Tick-Daten auf der Backtesting-Zeitreihe wird es zurückgegeben, wenn das Strategieprogramm die Schnittstelle aufruft.Beschreibung des Mechanismus für die Simulation der Backtest-Systeme.
Tick auf Bot-Ebene
Der Bot-Level-Backtest ist die tatsächlichen Tick-Level-Daten in der Bar-Zeitrahmenreihe. Für Strategien, die auf Tick-Level-Daten basieren, ist die Verwendung von echtem Marktniveau zum Backtest näher an der Realität. Im Bot-Level-Backtest sind Tick-Daten echte aufgezeichnete Daten, keine simulierte. Es unterstützt Tiefendaten, Datenspielung von Markthandeln, benutzerdefinierte Tiefe und jedes einzelne Handelsdaten. Die maximale Größe des Real-Markt-Level-Daten-Backtests beträgt maximal 50 MB, ohne Begrenzung des Backtest-Zeitrahmens innerhalb der oberen Grenze des Datensatzes. Wenn Sie den Backtest-Zeitrahmen so weit wie möglich vergrößern müssen, können Sie den Wert der Gear-Tiefe-Einstellung reduzieren und nicht jede einzelne Calltest-Tradingdaten verwenden, um den Backtest-Zeitrahmen zu erhöhen.GetDepth
, GetTrades
In einem Moment, in dem Marktdaten auf der ZeitleisteGetTicker
, GetTrades
, GetDepth
undGetRecords
wird die Zeit nicht mehrmals verschieben, wenn sich die Zeit auf der Backtest-Zeitleiste bewegt (was keinen Sprung zum nächsten Marktdatenmoment auslösen wird). Wiederholte Aufrufe zu einer der oben genannten Funktionen werden die Backtest-Zeit verschieben, um auf der Backtest-Zeitleiste zu bewegen (springen Sie zum nächsten Marktdatenmoment). Wenn das reale Marktniveau für den Backtest verwendet wird, wird eine frühere Zeit nicht empfohlen. Es kann in der vorzeitigen Zeitspanne keine Daten auf echtem Marktniveau geben.
Tick auf Bot-EbeneundTick auf SimulationsebeneDie Methode des Backtest-Systems, das als Transaktionsmatching-Mechanismus dient: Die Auftragstransaktionsmatching erfolgt nach dem angesehenen Preis und das gesamte Volumen wird gehandelt.
Das Backtesting-System unterstützt Backtesting-Strategien, die von:JavaScript
, TypeScript
, Python
, C++
, PINE
, MyLanguage
, Blockly
Visualisierung.
Der Rücktest vonJavaScriptundC++Handelsstrategien wird im Browser durchgeführt, und der echte Marktbot oderWexAppIm Rahmen der Evaluierung derWexAppDie Anwendungen werden von den Herstellern der Produkte und Dienstleistungen unterstützt.
Der Rücktest vonPythonDer Marktbetrieb und der Backtest beruhen beide auf derPythonWenn einige Bibliotheken benötigt werden, müssen sie manuell installiert werden (nur allgemeinePythondie Bibliotheken auf den öffentlichen FMZ Quant-Servern unterstützt werden).
Es unterstütztJavaScriptStrategie-Backtesting-Debugging in Chrome DevTools,Siehe.
Die Parameteroptimierungsfunktion des Backtestsystems der FMZ Quant Trading Platform besteht darin, die Parameterkombinationen gemäß jeder Parameteroptimierungsoption während des Backtests festzulegen.OptimierungOption auf der rechten Seite des Strategieparameters, um die Optimierungseinstellungen anzuzeigen.
JavaScript
, PINE
, undMy Language
, und unterstützt keine Parameteroptimierung für Vorlagen.Die Parameterkombinationen werden auf der Grundlage derminimum
, maximum
, undstep size
Das Backtesting-System wiederholt diese Parameterkombinationen für das Backtesting (d.h. jede Parameterkombination wird einmal zurück getestet).ZahlDer Typ kann im Backtesting-System optimiert werden.
In derStrategiebearbeitungsseite, in der Paginierung von
backtest
(über die Schaltfläche backtest
in der Strategiebearbeitung./*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
'''backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
'''
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
Klicken Sie auf JavaScript
/Python
/C++
/MyLanguage
/PINE
Sprachen beim Speichern von Backtest-Einstellungen in den Strategiecode:
MyLanguage:
(*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*)
PINE Sprache:
/*backtest
start: 2021-06-26 00:00:00
end: 2021-09-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
Das Backtesting-System der FMZ Quant Trading Platform unterstützt benutzerdefinierte Datenquellen, das Backtesting-System verwendet dieGET
Methode zur Anforderung einer benutzerdefinierten URL (öffentlich zugängliche URL), um eine externe Datenquelle für Backtest zu erhalten.
Parameter | Bedeutung | Erläuterung |
---|---|---|
Symbol | Name des Symbols | Spotmarktdaten wie:BTC_USDT , Futures-Marktdaten wieBTC_USDT.swap , Futures-Perpetual Contract Financing Rate Daten, wie zum Beispiel:BTC_USDT.funding , Futures-Perpetuum-Kontraktpreisindexdaten, wie zum Beispiel:BTC_USDT.index |
Eid | Auswechslungen | Der Wert der Vermögenswerte wird in den folgenden Zahlen angegeben: |
rund | Genauigkeit der Daten | True bedeutet, dass die spezifische Präzision in den Daten definiert wird, die von der benutzerdefinierten Datenquelle zurückgegeben werden.round=true |
Periode | K-Liniendatenperiode (Millisekunden) | wie z. B.:60000 ist ein Zeitraum von 1 Minute |
Tiefe | Tiefenebenen | 1-20 |
Handel | Ob Daten aufgeteilt werden müssen | (genau) / (falsch) |
von | Startzeit | Unix-Zeitstempel |
zu | Die Endzeit | Unix-Zeitstempel |
Einzelheiten | Anforderung von Daten für Symboldetails | Die Anfrage, die vom FMZ Quant Trading Platform Backtesting System an die benutzerdefinierte Datenquelle gesendet wird, ist festgesetzt:detail=true |
Gewohnheit | – | Dieser Parameter kann ignoriert werden |
Wenn die Datenquelle der Spot- und Futures-Börsenobjekte auf eine benutzerdefinierte Datenquelle (Feeder) eingestellt ist, sendet das Backtesting-System eine Anfrage an den benutzerdefinierten Datenquelle-Dienst:
http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Bitget&from=1351641600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_OKX&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=1
Das zurückgegebene Format muss eines der folgenden zwei Formate sein (das vom System automatisch erkannt werden):
Simulationsstufe Tick, Folgendes ist ein Beispiel für JSON-Daten:
{
"detail": {
"eid": "Binance",
"symbol": "BTC_USDT",
"alias": "BTCUSDT",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"marginCurrency": "USDT",
"basePrecision": 5,
"quotePrecision": 2,
"minQty": 0.00001,
"maxQty": 9000,
"minNotional": 5,
"maxNotional": 9000000,
"priceTick": 0.01,
"volumeTick": 0.00001,
"marginLevel": 10
},
"schema":["time", "open", "high", "low", "close", "vol"],
"data":[
[1564315200000, 9531300, 9531300, 9497060, 9497060, 787],
[1564316100000, 9495160, 9495160, 9474260, 9489460, 338]
]
}
Hier ist ein Beispiel für JSON-Daten:
Tick-Level-Backtestdaten (enhalten Informationen über die Markttiefe, und das Tiefenformat ist ein Array von[price, volume]
Es kann mehrere Ebenen der Tiefe haben,asks
für Preiserhöhungsbestellungen,bids
für die Preisnachlässigkeit).
{
"detail": {
"eid": "Binance",
"symbol": "BTC_USDT",
"alias": "BTCUSDT",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"marginCurrency": "USDT",
"basePrecision": 5,
"quotePrecision": 2,
"minQty": 0.00001,
"maxQty": 9000,
"minNotional": 5,
"maxNotional": 9000000,
"priceTick": 0.01,
"volumeTick": 0.00001,
"marginLevel": 10
},
"schema":["time", "asks", "bids", "trades", "close", "vol"],
"data":[
[1564315200000, [[9531300, 10]], [[9531300, 10]], [[1564315200000, 0, 9531300, 10]], 9497060, 787],
[1564316100000, [[9531300, 10]], [[9531300, 10]], [[1564316100000, 0, 9531300, 10]], 9497060, 787]
]
}
Feld | Beschreibung |
---|---|
Einzelheiten | Ausführliche Angaben zum angeforderten Datentyp, |
einschließlich des Namens der Währung, des Namens der Handelswährung, Präzision, Mindestbestellmenge usw. Es gibt die Attribute der Spalten in den Daten an. Anschrift, die kleinbuchstabenempfindlich ist und nur zeitlich begrenzt ist, offen, Hoch, niedrig, dicht, vol, bittet, bietet, handelt Daten. Die Spaltenstruktur, aufgezeichnete Daten nach dem Schema. Einstellungen.
Detailfeld
Feld | Beschreibung |
---|---|
Eid | Exchange Id, bitte beachten Sie, dass die Spot- und Futures- |
Einige Börsen haben unterschiedliche Eids. | |
Symbol | Code des Handelsprodukts |
Alias | Das Symbol in der Umschaltung entspricht dem aktuellen |
Code des Handelsprodukts | |
Basiswährung | Handelswährung |
ZitatWährung | Währung |
MargeWährung | Margenwährung |
BasisGenauigkeit | Genauigkeit der Transaktionswährung |
ZitatGenauigkeit | Genauigkeit bei der Preisgestaltung |
MinQty | Mindestbestellmenge |
maxQty | Höchstbestellmenge |
MinNotionale | Mindestbestellbetrag |
maxNationale | Höchstbestellbetrag |
PreisTick | Preissprung |
VolumenTick | Mindeständerungswert der Auftragsmenge (ein Sprung in |
Bestellmenge) | |
MarginEbene | Futures mit Hebelwert |
Vertrag Typ | Für dauerhafte Verträge:swap , die |
Das Backtest-System wird weiterhin die Finanzierungssätze und den Preisindex senden Bitte.
Spezielle Spaltenattributeasks
, bids
, trades
:
Feld | Beschreibung | Anmerkungen |
---|---|---|
Anfragen / Angebote | [Preis, Volumen],...] | Die Daten in |
DieLive Trading Level Tick
Datenbeispiel:[[9531300, 10]]
Das ist ein sehr gutes Beispiel.
Ich bin nicht derjenige, der das Problem hat, aber ich bin derjenige, der es hat.
Die Daten in derLive Trading Level Tick
Datenbeispiel:[[1564315200000, 0, 9531300, 10]]
|
Bei der Rückprüfung von Dauerverträgen an Futures-Börsen werden
Datenquellen erfordern auch zusätzliche Finanzierungsrate und Preisdaten
Das Backtesting-System wird weiterhin Anfragen senden.
für Finanzierungsquoten nur, wenn die angeforderten Marktdaten zurückgegeben werden
und das Detailfeld in der zurückgegebenen Struktur enthält die"contractType": "swap"
Schlüssel-Wert-Paar.
Wenn das Backtesting-System Daten über die Förderquote erhält, wird es weiterhin Anfragen nach Preisindexdaten zu senden.
Die Datenstruktur der Förderquote ist wie folgt:
{
"detail": {
"eid": "Futures_Binance",
"symbol": "BTC_USDT.funding",
"alias": "BTC_USDT.funding",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"marginCurrency": "",
"basePrecision": 8,
"quotePrecision": 8,
"minQty": 1,
"maxQty": 10000,
"minNotional": 1,
"maxNotional": 100000000,
"priceTick": 1e-8,
"volumeTick": 1e-8,
"marginLevel": 10
},
"schema": [
"time",
"open",
"high",
"low",
"close",
"vol"
],
"data": [
[
1584921600000,
-16795,
-16795,
-16795,
-16795,
0
],
[
1584950400000,
-16294,
-16294,
-16294,
-16294,
0
]
// ...
]
}
Ein Beispiel für eine Anfrage nach Finanzierungsraten aus dem Backtesting Das System ist:
http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.funding&to=1611244800&trades=0
Die Datenstruktur für den Preisindex ist wie folgt:
{
"detail": {
"eid": "Futures_Binance",
"symbol": "BTC_USDT.index",
"alias": "BTCUSDT",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"contractType": "index",
"marginCurrency": "USDT",
"basePrecision": 3,
"quotePrecision": 1,
"minQty": 0.001,
"maxQty": 1000,
"minNotional": 0,
"maxNotional": 1.7976931348623157e+308,
"priceTick": 0.1,
"volumeTick": 0.001,
"marginLevel": 10,
"volumeMultiple": 1
},
"schema": [
"time",
"open",
"high",
"low",
"close",
"vol"
],
"data": [
[1584921600000, 58172, 59167, 56902, 58962, 0],
[1584922500000, 58975, 59428, 58581, 59154, 0],
// ...
]
}
Beispiel für eine Anfrage nach Preisindexdaten, die durch das Backtesting gesendet wurde Das System ist:
http://customserver:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1351641600&period=86400000&round=true&symbol=BTC_USDT.index&to=1611244800&trades=0
Angabe der Datenquelle, z. B.http://120.24.2.20:9090/data
. Das benutzerdefinierte Datenquelle-Dienstprogramm wird mitGolang
:
package main
import (
"fmt"
"net/http"
"encoding/json"
)
func Handle (w http.ResponseWriter, r *http.Request) {
// e.g. set on backtest DataSourse: http://xxx.xx.x.xx:9090/data
// request: GET http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=OKX&from=1584921600&period=86400000&round=true&symbol=BTC_USDT&to=1611244800&trades=1
// http://xxx.xx.x.xx:9090/data?custom=0&depth=20&detail=true&eid=Futures_Binance&from=1599958800&period=3600000&round=true&symbol=BTC_USDT.swap&to=1611244800&trades=0
fmt.Println("request:", r)
// response
defer func() {
// response data
/* e.g. data
{
"detail": {
"eid": "Binance",
"symbol": "BTC_USDT",
"alias": "BTCUSDT",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"marginCurrency": "USDT",
"basePrecision": 5,
"quotePrecision": 2,
"minQty": 0.00001,
"maxQty": 9000,
"minNotional": 5,
"maxNotional": 9000000,
"priceTick": 0.01,
"volumeTick": 0.00001,
"marginLevel": 10
},
"schema": [
"time",
"open",
"high",
"low",
"close",
"vol"
],
"data": [
[1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151],
[1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738],
[1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875],
[1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777],
[1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292],
[1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666],
[1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405],
[1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768],
[1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797],
[1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692]
]
}
*/
// /* Simulation level Tick
ret := map[string]interface{}{
"detail": map[string]interface{}{
"eid": "Binance",
"symbol": "BTC_USDT",
"alias": "BTCUSDT",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"marginCurrency": "USDT",
"basePrecision": 5,
"quotePrecision": 2,
"minQty": 0.00001,
"maxQty": 9000,
"minNotional": 5,
"maxNotional": 9000000,
"priceTick": 0.01,
"volumeTick": 0.00001,
"marginLevel": 10,
},
"schema": []string{"time","open","high","low","close","vol"},
"data": []interface{}{
[]int64{1610755200000, 3673743, 3795000, 3535780, 3599498, 8634843151}, // 1610755200000 : 2021-01-16 08:00:00
[]int64{1610841600000, 3599498, 3685250, 3385000, 3582861, 8015772738}, // 1610841600000 : 2021-01-17 08:00:00
[]int64{1610928000000, 3582499, 3746983, 3480000, 3663127, 7069811875},
[]int64{1611014400000, 3662246, 3785000, 3584406, 3589149, 7961130777},
[]int64{1611100800000, 3590194, 3641531, 3340000, 3546823, 8936842292},
[]int64{1611187200000, 3546823, 3560000, 3007100, 3085013, 13500407666},
[]int64{1611273600000, 3085199, 3382653, 2885000, 3294517, 14297168405},
[]int64{1611360000000, 3295000, 3345600, 3139016, 3207800, 6459528768},
[]int64{1611446400000, 3207800, 3307100, 3090000, 3225990, 5797803797},
[]int64{1611532800000, 3225945, 3487500, 3191000, 3225420, 8849922692},
},
}
// */
/* Bot level Tick
ret := map[string]interface{}{
"detail": map[string]interface{}{
"eid": "Binance",
"symbol": "BTC_USDT",
"alias": "BTCUSDT",
"baseCurrency": "BTC",
"quoteCurrency": "USDT",
"marginCurrency": "USDT",
"basePrecision": 5,
"quotePrecision": 2,
"minQty": 0.00001,
"maxQty": 9000,
"minNotional": 5,
"maxNotional": 9000000,
"priceTick": 0.01,
"volumeTick": 0.00001,
"marginLevel": 10,
},
"schema": []string{"time", "asks", "bids", "trades", "close", "vol"},
"data": []interface{}{
[]interface{}{1610755200000, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{9531300, 10}}, []interface{}{[]int64{1610755200000, 0, 9531300, 10}}, 9497060, 787},
[]interface{}{1610841600000, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{9531300, 15}}, []interface{}{[]int64{1610841600000, 0, 9531300, 11}}, 9497061, 789},
},
}
*/
b, _ := json.Marshal(ret)
w.Write(b)
}()
}
func main () {
fmt.Println("listen http://localhost:9090")
http.HandleFunc("/data", Handle)
http.ListenAndServe(":9090", nil)
}
TeststrategieJavaScript
Beispiel:
/*backtest
start: 2021-01-16 08:00:00
end: 2021-01-22 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"OKX","currency":"BTC_USDT","feeder":"http://120.24.2.20:9090/data"}]
args: [["number",2]]
*/
function main() {
var ticker = exchange.GetTicker()
var records = exchange.GetRecords()
Log(exchange.GetName(), exchange.GetCurrency())
Log(ticker)
Log(records)
}
FMZ Quant Trading Platform hat für dieJavaScript
SprachePython
Sprache der lokalen Backtest-Engine, die die Einstellung der zugrunde liegenden K-Line Periode während des Backtests unterstützt.
Kurzschaltfläche zum Wechseln zwischen Strategie Ctrl +,
Sie können dann auf die Seite Ctrl
Drücken Sie die Taste.,
.
Abkürzung für die Sparstrategie
Verwenden Sie den Schlüssel.Ctrl + s
Sie müssen ihre Strategien retten.
Abkürzung für den Start der Strategie-Backtest
Verwenden Sie den Schlüssel.Ctrl + b
um
Der Quellcode des Sharpe-Algorithmus im Backtesting-System:
function returnAnalyze(totalAssets, profits, ts, te, period, yearDays) {
// force by days
period = 86400000
if (profits.length == 0) {
return null
}
var freeProfit = 0.03 // 0.04
var yearRange = yearDays * 86400000
var totalReturns = profits[profits.length - 1][1] / totalAssets
var annualizedReturns = (totalReturns * yearRange) / (te - ts)
// MaxDrawDown
var maxDrawdown = 0
var maxAssets = totalAssets
var maxAssetsTime = 0
var maxDrawdownTime = 0
var maxDrawdownStartTime = 0
var winningRate = 0
var winningResult = 0
for (var i = 0; i < profits.length; i++) {
if (i == 0) {
if (profits[i][1] > 0) {
winningResult++
}
} else {
if (profits[i][1] > profits[i - 1][1]) {
winningResult++
}
}
if ((profits[i][1] + totalAssets) > maxAssets) {
maxAssets = profits[i][1] + totalAssets
maxAssetsTime = profits[i][0]
}
if (maxAssets > 0) {
var drawDown = 1 - (profits[i][1] + totalAssets) / maxAssets
if (drawDown > maxDrawdown) {
maxDrawdown = drawDown
maxDrawdownTime = profits[i][0]
maxDrawdownStartTime = maxAssetsTime
}
}
}
if (profits.length > 0) {
winningRate = winningResult / profits.length
}
// trim profits
var i = 0
var datas = []
var sum = 0
var preProfit = 0
var perRatio = 0
var rangeEnd = te
if ((te - ts) % period > 0) {
rangeEnd = (parseInt(te / period) + 1) * period
}
for (var n = ts; n < rangeEnd; n += period) {
var dayProfit = 0.0
var cut = n + period
while (i < profits.length && profits[i][0] < cut) {
dayProfit += (profits[i][1] - preProfit)
preProfit = profits[i][1]
i++
}
perRatio = ((dayProfit / totalAssets) * yearRange) / period
sum += perRatio
datas.push(perRatio)
}
var sharpeRatio = 0
var volatility = 0
if (datas.length > 0) {
var avg = sum / datas.length;
var std = 0;
for (i = 0; i < datas.length; i++) {
std += Math.pow(datas[i] - avg, 2);
}
volatility = Math.sqrt(std / datas.length);
if (volatility !== 0) {
sharpeRatio = (annualizedReturns - freeProfit) / volatility
}
}
return {
totalAssets: totalAssets,
yearDays: yearDays,
totalReturns: totalReturns,
annualizedReturns: annualizedReturns,
sharpeRatio: sharpeRatio,
volatility: volatility,
maxDrawdown: maxDrawdown,
maxDrawdownTime: maxDrawdownTime,
maxAssetsTime: maxAssetsTime,
maxDrawdownStartTime: maxDrawdownStartTime,
winningRate: winningRate
}
}
Strategie-Editor
Strategie-Eingabefunktionen