Mittlere Preis-Abweichung in % für 4-Stunden-Klines berechnen



  • Hi,
    ich verwende zwei Libraries (eine binance-api und ta4j-core (... und erzwungenermaßen lombok)), aber weiß nicht genau, ob es die Funktion, die ich suche, schon gibt ... oder sie neu erstellt werden muss.

    Es gibt 4-Stunden-Klines. Ich möchte nun berechnen, inwieweit alle Klines durchschnittlich in Prozent vom Durchschnittspreis abweichen, also wie die Volatilität wäre.

    Skizze: https://i.postimg.cc/c1VhMV08/grafik.png , gesucht ist also jeweils die Boxhöhe.

    Hier mein Ansatz:

    import com.webcerebrium.binance.api.BinanceApi;
    import com.webcerebrium.binance.api.BinanceApiException;
    import com.webcerebrium.binance.datatype.BinanceCandlestick;
    import com.webcerebrium.binance.datatype.BinanceInterval;
    import com.webcerebrium.binance.datatype.BinanceSymbol;
    
    import org.ta4j.core.BarSeries;
    import org.ta4j.core.BaseBar;
    import org.ta4j.core.BaseBarSeriesBuilder;
    import org.ta4j.core.indicators.helpers.MedianPriceIndicator;
    import org.ta4j.core.indicators.statistics.MeanDeviationIndicator;
    import org.ta4j.core.indicators.statistics.StandardDeviationIndicator;
    import org.ta4j.core.indicators.statistics.VarianceIndicator;
    import org.ta4j.core.num.DecimalNum;
    
    import java.lang.reflect.Field;
    import java.math.BigDecimal;
    import java.nio.charset.Charset;
    import java.time.Duration;
    import java.time.Instant;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Locale;
    import java.util.Scanner;
    
    public class Main {
        public record VolatilityResult(double average, double deviation, double halfDeviation, double up, double lo) { }
    
        // private static final SimpleDateFormat sdf = new SimpleDateFormat();
        private static final BinanceApi api = new BinanceApi();
    
        public static String f(final Object dObj) {
            if (dObj instanceof BigDecimal) {
                return ((BigDecimal) dObj).toPlainString();
            }
            return String.format(Locale.ROOT, "%.9f", (Double) dObj);
        }
    
        public static void print(final VolatilityResult vr) {
            System.out.println("vr.average   = " + f(vr.average));
            System.out.println("vr.deviation = " + f(vr.deviation));
            System.out.println("vr.halfDevi  = " + f(vr.halfDeviation));
            System.out.println("vr.up        = " + f(vr.up));
            System.out.println("vr.lo        = " + f(vr.lo));
        }
    
        public static BaseBar convertBinanceCandlestickToBaseBar(final BinanceCandlestick cs) {
            return new BaseBar(
                    Duration.ofHours(4),
                    ZonedDateTime.ofInstant(
                            Instant.ofEpochMilli(cs.getOpenTime()), ZoneId.systemDefault()),
                    cs.getOpen(),
                    cs.getHigh(),
                    cs.getLow(),
                    cs.getClose(),
                    cs.getVolume());
        }
    
        public static List<BinanceCandlestick> getBinanceCandlesticks(final String name)
                throws BinanceApiException, Exception {
            //noinspection SpellCheckingInspection
            BinanceSymbol ethbtc = new BinanceSymbol("ETHBTC");
            Field symbol = ethbtc.getClass().getDeclaredField("symbol");
            symbol.setAccessible(true);
            symbol.set(ethbtc, name);
            return api.klines(ethbtc, BinanceInterval.FOUR_HOURS, 31 * 6, null);
        }
    
        public static VolatilityResult getAvgVolatility1(final List<BinanceCandlestick> klines) {
            int n = klines.size() - 1;
            double sumAverage = 0;
            double sumVolatility = 0;
            for (int i = 0; i < n; i++) {
                BinanceCandlestick cs = klines.get(i);
                sumAverage += (cs.getHigh().doubleValue() + cs.getLow().doubleValue()) / 2;
                sumVolatility += cs.getHigh().doubleValue() / cs.getLow().doubleValue();
            }
            double average = sumAverage / n;
            double deviation = (sumVolatility / n - 1) * 100;
            double halfDeviation = deviation / 2;
            double up = average + average * ((sumVolatility / n - 1) / 2);
            double lo = average - average * ((sumVolatility / n - 1) / 2);
            return new VolatilityResult(average, deviation, halfDeviation, up, lo);
        }
    
        public static double[] getAvgVolatility2(final List<BinanceCandlestick> klines) {
            int n = klines.size() - 1;
            BarSeries series = new BaseBarSeriesBuilder().withName("my_series").build();
            for (int i = 0; i < n; i++) {
                BinanceCandlestick cs = klines.get(i);
                series.addBar(convertBinanceCandlestickToBaseBar(cs));
            }
            MedianPriceIndicator mpi = new MedianPriceIndicator(series);
            VarianceIndicator vi = new VarianceIndicator(mpi, n);
            StandardDeviationIndicator sdi = new StandardDeviationIndicator(mpi, n);
            MeanDeviationIndicator mdi = new MeanDeviationIndicator(mpi, n);
            return new double[]{
                    vi.getValue(n - 1).doubleValue(),
                    sdi.getValue(n - 1).doubleValue(),
                    mdi.getValue(n - 1).doubleValue()
            };
        }
    
        public static void main(final String[] args) throws BinanceApiException, Exception {
            System.out.println("Enter symbol:");
            String symbol = new Scanner(System.in, Charset.defaultCharset()).nextLine();
            List<BinanceCandlestick> cs = getBinanceCandlesticks(symbol);
            VolatilityResult v1 = getAvgVolatility1(cs);
            double[] v2 = getAvgVolatility2(cs);
            print(v1);
            System.out.println(f(v2[0]));
            System.out.println(f(v2[1]));
            System.out.println(f(v2[2]));
        }
    }
    

    Die Ausgabe ist für "ETHBTC" zurzeit:

    Enter symbol:
    ETHBTC
    
    vr.average   = 0.068484319
    vr.deviation = 0.909483930
    vr.halfDevi  = 0.454741965
    vr.up        = 0.068795746
    vr.lo        = 0.068172892
    0.000006160
    0.002481983
    0.002024274
    

    ... ich glaube, ich suche nach der average absolute deviation (AAD), oder?: https://en.wikipedia.org/wiki/Average_absolute_deviation


Anmelden zum Antworten