Antwort

Ist das Sortino Ratio Skript richtig?

2 Antworten

eastpeace

Kunde, bbp_participant, community, sq-ultimate, 305 Antworten.

Profil besuchen

vor 4 Jahren #257305

`/*
* Copyright (c) 2017-2018, StrategyQuant - Alle Rechte vorbehalten.
*
* Der Code in dieser Datei wurde in dem guten Glauben erstellt, dass er korrekt ist und das tut, was er soll.
* Wenn Sie einen Fehler in diesem Code gefunden haben ODER einen Verbesserungsvorschlag haben ODER Sie möchten
* Ihren eigenen Codeschnipsel in unsere Standardbibliothek einfügen möchten, kontaktieren Sie uns bitte unter:
* https://roadmap.strategyquant.com
*
* Dieser Code kann nur für StrategyQuant-Produkte verwendet werden.
* Jeder Besitzer einer gültigen (kostenlosen, Test- oder kommerziellen) Lizenz eines beliebigen StrategyQuant-Produkts
* darf diesen Code ohne Einschränkungen frei verwenden, kopieren, verändern oder davon abgeleitete Arbeiten erstellen,
* in allen StrategyQuant-Produkten zu verwenden und seine Änderungen oder abgeleiteten Arbeiten zu teilen
* mit der StrategyQuant-Gemeinschaft.
*
* DIE SOFTWARE WIRD OHNE MÄNGELGEWÄHR UND OHNE JEGLICHE AUSDRÜCKLICHE ODER STILLSCHWEIGENDE GARANTIE ZUR VERFÜGUNG GESTELLT,
* EINSCHLIESSLICH, ABER NICHT BESCHRÄNKT AUF DIE GARANTIEN DER MARKTGÄNGIGKEIT, DER EIGNUNG FÜR EINEN BESTIMMTEN
* ZWECK UND NICHT-VERLETZUNG. IN KEINEM FALL SIND DIE AUTOREN HAFTBAR FÜR JEGLICHE FORDERUNGEN, SCHÄDEN
* ODER SONSTIGE HAFTUNG, SEI ES AUS VERTRAG, UNERLAUBTER HANDLUNG ODER ANDERWEITIG, DIE SICH AUS,
* AUS ODER IN VERBINDUNG MIT DER SOFTWARE ODER DER NUTZUNG ODER DEM SONSTIGEN UMGANG MIT DER SOFTWARE.
*
*/
Paket SQ.Columns.Databanks;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.strategyquant.lib.L;
import com.strategyquant.lib.SQTime;
import com.strategyquant.lib.SQUtils;
import com.strategyquant.lib.SettingsMap;
import com.strategyquant.tradinglib.DatabankColumn;
import com.strategyquant.tradinglib.Directions;
import com.strategyquant.tradinglib.Order;
import com.strategyquant.tradinglib.OrdersList;
import com.strategyquant.tradinglib.PlTypes;
import com.strategyquant.tradinglib.SQStats;
import com.strategyquant.tradinglib.StatsTypeCombination;
import com.strategyquant.tradinglib.ValueTypes;

import SQ.Functions.StatFunctions;
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import it.unimi.dsi.fastutil.ints.Int2DoubleAVLTreeMap;

public class Sortino extends DatabankColumn {
public static final Logger Log = LoggerFactory.getLogger("Sortino");

private final long DAY_DURATION = 24 * 60* 60 * 1000;

//————————————————————————
//————————————————————————
//————————————————————————

public Sortino() {
super(L.t("Sortino Ratio"), DatabankColumn.Decimal2, ValueTypes.Maximize, 0, -1, 1);

this.setTooltip(L.t("Sortino Ratio (annualisiert)"));

// Beschränken Sie die Sortino-Berechnung nur auf den PL-Typ Geld (wir berechnen keinen separaten Sortino für % oder Pips-Ergebnisse, es ist dasselbe wie für Geld)
setPLTypeRestrictions(PlTypes.Money);

// Beschränkung der Sortino-Berechnung auf beide Richtungen, keine Sharpe-Berechnung für Long- oder Short-Ergebnisse
setDirectionRestrictions(Directions.Both);
}

//————————————————————————

@Override
public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort) throws Exception {

DoubleArrayList dailyReturnsPct = computeDailyReturn(ordersList);

double returnsMean = StatFunctions.computeAverage(dailyReturnsPct);

double returnsStddev = computeLowStdev(returnsMean, dailyReturnsPct,0,-1);

double Sortino = Math.sqrt(252) * SQUtils.safeDivide(returnsMean, returnsStddev);

return round2(Sortino);
}

//————————————————————————

private DoubleArrayList computeDailyReturn(OrdersList ordersList) {
if(ordersList.size() == 0) {
null zurückgeben;
}

// Wir nehmen 5% Jahresgewinn als Benchmark für die Berechnung der Sortino Ratio
double benchmark = 0,05/252;

// Berechnung des ersten und letzten Datums
long firstDate = Long.MAX_VALUE;
long lastDate = -1;

for(int i=0; i<ordersList.size(); i++) {
Auftrag o = ordersList.get(i);

if(o.CloseTime < firstDate) {
firstDate = o.CloseTime;
}

if(o.CloseTime > lastDate) {
lastDate = o.CloseTime;
}
}

// so einrichten, dass er am Montag beginnt
erstesDatum = SQTime.correctDayStart(erstesDatum);
int firstDateDow = SQTime.getDayOfWeek(firstDate);

// Erstellung eines Arrays von Rückgaben für jeden Tag, der nicht Samstag/Sonntag ist
DoubleArrayList returns = new DoubleArrayList();
int index = 1;
long startDate = firstDate;
while(true) {
int weekIndex = index+firstDateDow-1;
if(weekIndex > 7) {
int weeks = weekIndex / 7;
weekIndex -= weeks*7;
}
if(weekIndex % 6 != 0 && weekIndex % 7 != 0) {
// Samstage und Sonntage auslassen
returns.add(-benchmark);
}

index++;

startDate += DAY_DURATION;

if(startDate > lastDate) {
Pause;
}
}

// Gehen Sie jetzt durch die Aufträge und fügen Sie PctPL für jeden Auftrag hinzu.
for(int i=0; i<ordersList.size(); i++) {
Auftrag o = ordersList.get(i);

int dow = SQTime.getDayOfWeek(o.CloseTime);
if(dow == 6 || dow == 7) {
// Samstage und Sonntage auslassen
weiter;
}

long closeTime = SQTime.correctDayStart(o.CloseTime);

index = (int) ((closeTime - firstDate) / DAY_DURATION);

// Wochenenden abziehen
if(index > firstDateDow) {
Index -= 2;
}
int weeks = index / 7;
Index -= Wochen*2;

if(index = returns.size()) {
weiter;
}

double currentDayPL = returns.getDouble(index);
returns.set(index, currentDayPL+o.PctPL);
}

kehrt zurück;
}

public static double computeLowStdev(double mean, DoubleArrayList values, int from, int to ) {
if(werte == null || werte.größe() == 0) {
0 zurückgeben;
}

if(to == -1) {
to = values.size();
}

double sum = 0, stdev, pl;
for (int i = from; i < to; i++) {
pl = values.getDouble(i);
Summe += Math.pow((Math.min(pl - mean,0)), 2d);
}
stdev = (double) Math.sqrt(Summe / ((double) (bis - von)));
zurück (stdev);
}
}

0

tomas262

Administrator, sq-ultimate, 2 Antworten.

Profil besuchen

vor 4 Jahren #257432

Hallo, ich habe es überprüft, aber das Ergebnis ist bei mir 0. Ich vermute, dass etwas mit der Funktion computeLowStdev nicht stimmt, aber ich bin selbst kein Java-Programmierer. Die Entwickler werden den Sortino-Code überprüfen, damit er in die folgenden SQ-Builds aufgenommen werden kann

0

eastpeace

Kunde, bbp_participant, community, sq-ultimate, 305 Antworten.

Profil besuchen

vor 3 Jahren #258033

 

Es hat ein Ergebnis. Vielleicht müssen Sie SQ neu starten und erneut testen.

Aber ich habe gerade die Sharpe Ratio kopiert und bin mir nicht sicher, ob sie korrekt ist. Vor allem bin ich verwirrt über die Statistik der täglichen Rendite.

0

Ansicht von 2 Antworten - 1 bis 2 (von insgesamt 2)