All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fluxtion.server.lib.pnl.calculator.DerivedRateNode Maven / Gradle / Ivy

There is a newer version: 0.1.29
Show newest version
/*
 * SPDX-FileCopyrightText: © 2024 Gregory Higgins 
 * SPDX-License-Identifier: AGPL-3.0-only
 */

package com.fluxtion.server.lib.pnl.calculator;


import com.fluxtion.runtime.annotations.OnEventHandler;
import com.fluxtion.runtime.annotations.builder.FluxtionIgnore;
import com.fluxtion.runtime.dataflow.groupby.GroupBy;
import com.fluxtion.runtime.dataflow.groupby.GroupByHashMap;
import com.fluxtion.server.lib.pnl.MidPrice;
import com.fluxtion.server.lib.pnl.MtmInstrument;
import com.fluxtion.server.lib.pnl.refdata.Instrument;
import lombok.Data;
import org.jgrapht.GraphPath;
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
import org.jgrapht.graph.DefaultWeightedEdge;

import java.util.Map;

@Data
public class DerivedRateNode {

    @FluxtionIgnore
    private final DefaultDirectedWeightedGraph graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);
    @FluxtionIgnore
    private final GroupByHashMap derivedRates = new GroupByHashMap<>();
    @FluxtionIgnore
    private final BellmanFordShortestPath shortestPath = new BellmanFordShortestPath<>(graph);
    private Instrument mtmInstrument = Instrument.INSTRUMENT_USD;

    @OnEventHandler
    public boolean updateMtmInstrument(MtmInstrument mtmInstrumentUpdate) {
        boolean change = mtmInstrument != mtmInstrumentUpdate.instrument();
        mtmInstrument = mtmInstrumentUpdate.instrument();
        return change;
    }

    @OnEventHandler
    public boolean midRate(MidPrice midPrice) {
        Instrument dealtInstrument = midPrice.getSymbol().dealtInstrument();
        Instrument contraInstrument = midPrice.getSymbol().contraInstrument();

        //no self cycles allowed
        if (dealtInstrument == contraInstrument | dealtInstrument == null | contraInstrument == null) {
            return false;
        }

        double rate = midPrice.getRate();
        double logRate = Math.log10(rate);
        double logInverseRate = Math.log10(1 / rate);

        graph.addVertex(dealtInstrument);
        graph.addVertex(contraInstrument);
        if (graph.containsEdge(dealtInstrument, contraInstrument)) {
            graph.setEdgeWeight(dealtInstrument, contraInstrument, logRate);
            graph.setEdgeWeight(contraInstrument, dealtInstrument, logInverseRate);
        } else {
            graph.setEdgeWeight(graph.addEdge(dealtInstrument, contraInstrument), logRate);
            graph.setEdgeWeight(graph.addEdge(contraInstrument, dealtInstrument), logInverseRate);
        }
        return false;
    }

    public boolean isMtmSymbol(MidPrice midPrice) {
        return midPrice.getOppositeInstrument(mtmInstrument) != null;
    }

    public Instrument getMtmContraInstrument(MidPrice midPrice) {
        return midPrice.getOppositeInstrument(mtmInstrument);
    }

    public double getMtMRate(MidPrice midPrice) {
        return midPrice.getRateForInstrument(mtmInstrument);
    }

    public GroupBy addDerived(
            GroupBy rateMapGroupBy,
            GroupBy positionMapGroupBy) {

        Map rateMap = rateMapGroupBy.toMap();
        Map positionMap = positionMapGroupBy.toMap();

        derivedRates.fromMap(rateMap);
        Map derivedRateMap = derivedRates.toMap();
        derivedRateMap.put(mtmInstrument, 1.0);

        positionMap.keySet().forEach(
                i -> {
                    derivedRateMap.computeIfAbsent(i, positionInstrument -> {
                        if (graph.containsVertex(positionInstrument) & graph.containsVertex(mtmInstrument)) {
                            GraphPath path = shortestPath.getPath(positionInstrument, mtmInstrument);
                            double log10Rate = shortestPath.getPathWeight(positionInstrument, mtmInstrument);
                            return Double.isInfinite(log10Rate) ? Double.NaN : Math.pow(10, log10Rate);
                        }
                        return Double.NaN;
                    });
                }
        );
        return derivedRates;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy