- Registriert
- Jan. 2021
- Beiträge
- 3.270
Lol, also ist jetzt richtig == falsch? Verstehe. Danke für deinen nutzlosen Kommentar.
Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
+------------+-------+--------+----------------------+
| | Preis | Anzahl | Gewinn bei Verkauf |
+------------+-------+--------+----------------------+
| 1. Kauf | 100 | 2 | 2*50=100 |
+------------+-------+--------+----------------------+
| 2. Kauf | 50 | 2 | 1*100=100 |
+------------+-------+--------+----------------------+
| 3. Verkauf | 150 | -3 | 200 |
+------------+-------+--------+----------------------+
+------------+-------+--------+----------------------+
| | Preis | Anzahl | Gewinn bei Verkauf |
+------------+-------+--------+----------------------+
| 1. Kauf | 50 | 2 | 2*100=200 |
+------------+-------+--------+----------------------+
| 2. Kauf | 100 | 2 | 1*50=50 |
+------------+-------+--------+----------------------+
| 3. Verkauf | 150 | -3 | 250 |
+------------+-------+--------+----------------------+
import java.util.ArrayList;
import java.util.Comparator;
public class ProfitCalculatorTest {
private record Transaction(boolean isBuy, double price, double quantity) {
}
private final ArrayList<Transaction> transactions = new ArrayList<>();
public void buy(double quantity, double price) {
transactions.add(new Transaction(true, price, quantity));
System.out.println("Gekauft: " + quantity + " Aktien zu " + price + " EUR.");
System.out.println();
}
public void sell(double quantity, double price) {
double[] profit = calculatePartialProfitAtPrice(quantity, price);
transactions.add(new Transaction(false, price, quantity));
System.out.println("Verkauft: " + quantity + " Aktien zu " + price + " EUR.");
if (profit != null) {
System.out.println("Partial profit: " + profit[0] + " EUR.");
System.out.println("Percentage: " + profit[1] + " %.");
} else {
System.out.println("Warnung: Nicht genügend Aktien zum Verkauf vorhanden.");
}
System.out.println();
}
public double[] calculatePartialProfitAtPrice(double quantity, double price) {
final double quoteToFind = quantity;
double sellQuote = 0;
double buyQuote = 0;
for (Transaction transaction : transactions) {
if (transaction.isBuy()) {
buyQuote += transaction.quantity();
} else {
sellQuote += transaction.quantity();
}
}
if (quoteToFind + sellQuote > buyQuote) {
return null;
}
double openQuote = quoteToFind + sellQuote;
ArrayList<Transaction> tempList = new ArrayList<>(transactions);
tempList.sort(Comparator.comparing(Transaction::price));
for (Transaction transaction : tempList) {
if (transaction.isBuy()) {
openQuote -= transaction.quantity();
if (openQuote <= 0) {
double profit = quoteToFind * price - quoteToFind * transaction.price();
double percentage = (price / transaction.price() - 1.0) * 100.0;
return new double[]{profit, percentage};
}
}
}
return null;
}
public static void main(String[] args) {
ProfitCalculatorTest calculator = new ProfitCalculatorTest();
calculator.buy(50, 50.0);
calculator.buy(100, 60.0);
calculator.sell(10, 51.0);
calculator.sell(35, 51.0);
calculator.sell(10, 51.0); // Hier fehlt ein "Split" in der Berechnung
calculator.sell(95, 59.0);
calculator.sell(1, 61.0);
}
}
Ja, siehe auch mein Beispiel in der main()-Methode ...Wo bin ich hier schrieb:Passt das in deinen aktuellen Kontext?
CyborgBeta schrieb:tempList.sort(Comparator.comparing(Transaction:rice));
Du musst halt vor allem den Verkauf über mehrere Kauf-Transaktionen hinweg berücksichtigen.CyborgBeta schrieb:Eigentlich können ja 5 Anteile mit Gewinn verkauft werden (Zeile 66), das wird aber noch nicht berücksichtigt ...
Weil sich anhand der Transaktionen mit den niedrigsten Preisen der Profit orientiert (vorausgesetzt, sie wurden noch nicht "realisiert", also vorher verkauft).Wo bin ich hier schrieb:Naja, wieso sortierst du nach all den Kommentaren hier immer noch nach dem Preis?
import java.util.ArrayList;
import java.util.Comparator;
public class ProfitCalculatorTest {
private record Transaction(boolean isBuy, double price, double quantity) {
}
private final ArrayList<Transaction> transactions = new ArrayList<>();
public void buy(double quantity, double price) {
transactions.add(new Transaction(true, price, quantity));
System.out.println("Gekauft: " + quantity + " Aktien zu " + price + " EUR.");
System.out.println();
}
public void sell(double quantity, double price) {
double[] profit = calculatePartialProfitAtPrice(quantity, price);
transactions.add(new Transaction(false, price, quantity));
System.out.println("Verkauft: " + quantity + " Aktien zu " + price + " EUR.");
if (profit != null) {
System.out.println("Partial profit: " + profit[0] + " EUR.");
System.out.println("Percentage: " + profit[1] + " %.");
} else {
System.out.println("Warnung: Nicht genügend Aktien zum Verkauf vorhanden.");
}
System.out.println();
}
public double[] calculatePartialProfitAtPrice(double quantity, double price) {
final double quoteToFind = quantity;
double sellQuote = 0;
double buyQuote = 0;
for (Transaction transaction : transactions) {
if (transaction.isBuy()) {
buyQuote += transaction.quantity();
} else {
sellQuote += transaction.quantity();
}
}
if (quoteToFind + sellQuote > buyQuote) {
return null;
}
double openQuote1 = sellQuote;
double openQuote2 = quoteToFind;
double profit = 0;
ArrayList<Transaction> tempList = new ArrayList<>(transactions);
tempList.sort(Comparator.comparing(Transaction::price));
for (Transaction transaction : tempList) {
if (transaction.isBuy()) {
openQuote1 -= transaction.quantity();
if (openQuote1 <= 0) {
if (transaction.quantity() <= openQuote2) {
profit += transaction.quantity() * (price - transaction.price());
openQuote2 -= transaction.quantity();
} else {
profit += openQuote2 * (price - transaction.price());
return new double[]{profit, (quoteToFind * price + profit) / (quoteToFind * price) * 100 - 100};
}
}
}
}
return null;
}
public static void main(String[] args) {
ProfitCalculatorTest calculator = new ProfitCalculatorTest();
calculator.buy(100, 60.0);
calculator.buy(50, 50.0);
calculator.sell(55, 51.0); // 0.178 %
calculator.sell(10, 61.0); // 1.64 %
calculator.sell(84, 59.0); // -1.69 %
calculator.sell(0.1, 61.0); // 1.64 %
calculator.sell(1, 61.0); // not enough stocks
}
}
(quoteToFind * price + profit) / (quoteToFind * price) * 100 - 100
public static void main(String[] args) {
ProfitCalculatorTest calculator = new ProfitCalculatorTest();
calculator.buy(100, 60.0);
calculator.buy(50, 50.0);
calculator.sell(45, 50);
calculator.sell(20, 60); // 20 * 60 = 1200 vs. 5 * 50 + 15 * 60 = 1150 <=> sollte 4.3 % sein, ist aber 16.7 % => Fehler
calculator.sell(84, 60);
calculator.sell(0.1, 60);
calculator.sell(0.9, 60);
}
calculator.buy(100, 60.0);
calculator.buy(50, 50.0);
calculator.sell(20, 51.0);
calculator.sell(20, 51.0);
calculator.sell(20, 51.0);
Ja, die Prozentberechnung stimmt nicht, vermute ich.Wo bin ich hier schrieb:Zuvor noch ein anderes Problem in Richtung teilweiser Abverkauf
if (transaction.quantity() <= openQuote2) {
if (transaction.quantity() < openQuote2) {
Stimmt:Wo bin ich hier schrieb:Der angegebene "Partial profit: 20.0 EUR." ist doch bereits daneben?
Du hast 10*1 + 10*-9 = -80.
20*51 - (10*50 + 10*60) = -80
Diesmal geht es nicht um Genauigkeit ... da reichen schon zwei Prozentnachkommastellen. Der kumulative Fehler dürfte auch bei ca. 10 Transaktionen nicht allzu hoch sein.mental.dIseASe schrieb:nimm niemals double, sondern BigDecimal
Selbstverständlich dein gutes recht. Aber nicht beleidigend werden.mental.dIseASe schrieb:Fachlich habe ich keine Lust, mich damit auseinanderzusetzen
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
public class ProfitCalculatorTest {
private record Transaction(boolean isBuy, double price, double quantity) {
}
private final ArrayList<Transaction> transactions = new ArrayList<>();
public void buy(double quantity, double price) {
transactions.add(new Transaction(true, price, quantity));
System.out.println("Gekauft: " + quantity + " Aktien zu " + price + " EUR.");
System.out.println();
}
public void sell(double quantity, double price) {
double[] profit = calculatePartialProfitAtPrice(quantity, price);
if (profit != null) {
transactions.add(new Transaction(false, price, quantity));
if (isQuoteEmpty()) {
// New epoch: all quotes are sold
transactions.clear();
}
System.out.println("Verkauft: " + quantity + " Aktien zu " + price + " EUR.");
System.out.println("Partial profit: " + profit[0] + " EUR.");
System.out.println("Percentage: " + profit[1] + " %.");
} else {
System.out.println("Warnung: Nicht genügend Aktien zum Verkauf vorhanden.");
}
System.out.println();
}
public boolean isQuoteEmpty() {
double sellQuote = 0;
double buyQuote = 0;
for (Transaction transaction : transactions) {
if (transaction.isBuy()) {
buyQuote += transaction.quantity();
} else {
sellQuote += transaction.quantity();
}
}
double e = 0.001;
return sellQuote + e >= buyQuote;
}
public double[] calculatePartialProfitAtPrice(double quantity, double price) {
final double quoteToFind = quantity; // The total amount of quotes to find
// Calculate the total amount of bought and sold quotes
double sellQuote = 0;
double buyQuote = 0;
for (Transaction transaction : transactions) {
if (transaction.isBuy()) {
buyQuote += transaction.quantity();
} else {
sellQuote += transaction.quantity();
}
}
// If the total amount of sold quotes is greater than the total amount of bought quotes, return null, because the transaction is invalid
if (quoteToFind + sellQuote > buyQuote) {
return null;
}
// Create a temporary list of transactions and sort it by price
ArrayList<Transaction> tempList = new ArrayList<>(transactions);
tempList.sort(Comparator.comparing(Transaction::price));
// Remove the bought quotes from the list until the total amount of sold quotes is reached
double open = sellQuote;
for (Iterator<Transaction> iterator = tempList.iterator(); iterator.hasNext(); ) {
Transaction transaction = iterator.next();
iterator.remove();
if (transaction.isBuy()) {
if (open > transaction.quantity()) {
open -= transaction.quantity();
} else {
tempList.addFirst(new Transaction(true, transaction.price(), transaction.quantity() - open));
break;
}
}
}
// Calculate the profit
open = quoteToFind;
double profit = 0;
for (Transaction transaction : tempList) {
if (transaction.isBuy()) {
if (open > transaction.quantity()) {
open -= transaction.quantity();
profit += transaction.quantity() * (price - transaction.price());
} else {
profit += open * (price - transaction.price());
return new double[]{profit, (quoteToFind * price + profit) / (quoteToFind * price) * 100 - 100};
}
}
}
// Should never be reached
return null;
}
public static void main(String[] args) {
ProfitCalculatorTest calculator = new ProfitCalculatorTest();
calculator.buy(100, 60.0);
calculator.buy(50, 50.0);
calculator.sell(20, 50);
calculator.sell(20, 50);
calculator.sell(110, 60);
calculator.sell(1, 60);
calculator.buy(100, 60.0);
calculator.buy(50, 50.0);
calculator.sell(20, 50);
calculator.sell(20, 50);
calculator.sell(20, 50);
calculator.sell(80, 60);
calculator.sell(100, 60);
calculator.buy(100, 65.0);
calculator.sell(110, 65);
calculator.sell(0.01, 65);
}
}
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.function.Predicate;
public class ProfitCalculatorTest {
private record Transaction(boolean isBuy, double price, double quantity) {
}
private final ArrayList<Transaction> transactions = new ArrayList<>();
public void buy(double quantity, double price) {
transactions.add(new Transaction(true, price, quantity));
System.out.println("Gekauft: " + quantity + " Aktien zu " + price + " EUR.");
System.out.println();
}
public void sell(double quantity, double price) {
double[] profit = calculatePartialProfitAtPrice(quantity, price);
if (profit != null) {
transactions.add(new Transaction(false, price, quantity));
System.out.println("Verkauft: " + quantity + " Aktien zu " + price + " EUR.");
System.out.println("Partial profit: " + profit[0] + " EUR.");
System.out.println("Percentage: " + profit[1] + " %.");
} else {
System.out.println("Warnung: Nicht genug Aktien zum Verkauf vorhanden.");
}
System.out.println();
}
private ArrayList<Transaction> removeOldTransactions() {
ArrayList<Transaction> tempList = new ArrayList<>(transactions);
double sum = 0;
a:
while (true) {
for (int i = 0; i < tempList.size(); i++) {
Transaction transaction = tempList.get(i);
if (transaction.isBuy()) {
sum += transaction.quantity();
} else {
sum -= transaction.quantity();
}
if (sum <= 0.0000001) {
tempList = new ArrayList<>(tempList.subList(i + 1, tempList.size()));
sum = 0;
continue a;
}
}
break;
}
return tempList;
}
public double[] calculatePartialProfitAtPrice(double quantity, double price) {
final double quoteToFind = quantity; // The total amount of quotes to find
// Get a copy of the transactions list without the old transactions
ArrayList<Transaction> tempList = removeOldTransactions();
// Calculate the total amount of bought and sold quotes
double sellQuote = tempList.stream().filter(Predicate.not(Transaction::isBuy)).mapToDouble(Transaction::quantity).sum();
double buyQuote = tempList.stream().filter(Transaction::isBuy).mapToDouble(Transaction::quantity).sum();
// If the total amount of sold quotes is greater than the total amount of bought quotes, return null, because the transaction is invalid
if (quoteToFind + sellQuote > buyQuote) {
return null;
}
// Sort the list by price to get the lowest prices first
tempList.sort(Comparator.comparing(Transaction::price));
// Remove the bought quotes from the list until the total amount of sold quotes is reached
double open = sellQuote;
for (Iterator<Transaction> iterator = tempList.iterator(); iterator.hasNext(); ) {
Transaction transaction = iterator.next();
iterator.remove();
if (transaction.isBuy()) {
if (open > transaction.quantity()) {
open -= transaction.quantity();
} else {
tempList.addFirst(new Transaction(true, transaction.price(), transaction.quantity() - open));
break;
}
}
}
// Calculate the profit
open = quoteToFind;
double profit = 0;
for (Transaction transaction : tempList) {
if (transaction.isBuy()) {
if (open > transaction.quantity()) {
open -= transaction.quantity();
profit += transaction.quantity() * (price - transaction.price());
} else {
profit += open * (price - transaction.price());
return new double[]{profit, (quoteToFind * price + profit) / (quoteToFind * price) * 100 - 100};
}
}
}
// Should never be reached
return null;
}
public static void main(String[] args) {
ProfitCalculatorTest calculator = new ProfitCalculatorTest();
calculator.buy(100, 60.0);
calculator.buy(50, 50.0);
calculator.sell(20, 50);
calculator.sell(20, 50);
calculator.sell(110, 60);
calculator.sell(1, 60);
calculator.buy(100, 60.0);
calculator.buy(50, 50.0);
calculator.sell(20, 50);
calculator.sell(20, 50);
calculator.sell(20, 50);
calculator.sell(80, 60);
calculator.sell(100, 60);
calculator.buy(100, 65.0);
calculator.sell(110, 65);
calculator.sell(0.01, 65);
}
}
private ArrayList<Transaction> getRelevantTransactions() {
ArrayList<Transaction> tempList = new ArrayList<>(transactions);
double sum = 0;
int lastZeroIndex = -1;
for (int i = 0; i < tempList.size(); i++) {
Transaction transaction = tempList.get(i);
if (transaction.isBuy()) {
sum += transaction.quantity();
} else {
sum -= transaction.quantity();
}
if (sum <= 0.0000001) {
sum = 0;
lastZeroIndex = i;
}
}
return lastZeroIndex == -1 ? tempList : new ArrayList<>(tempList.subList(lastZeroIndex + 1, tempList.size()));
}
private ArrayList<Transaction> getRelevantTransactions() {
ArrayList<Transaction> tempList = new ArrayList<>(transactions);
double[] sum = {0};
int[] lastZeroIndex = {-1};
IntStream.range(0, tempList.size()).forEach(i -> {
Transaction transaction = tempList.get(i);
if (transaction.isBuy()) {
sum[0] += transaction.quantity();
} else {
sum[0] -= transaction.quantity();
}
if (sum[0] <= 0.0000001) {
sum[0] = 0;
lastZeroIndex[0] = i;
}
});
return lastZeroIndex[0] == -1 ? tempList : new ArrayList<>(tempList.subList(lastZeroIndex[0] + 1, tempList.size()));
}
-1
darf 0
sein.Nicht ganz korrekt. Ein Stream-Prinzip in Java ist: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#accessing-local-variables (man darf umliegende Variablen nicht direkt verändern)marcOcram schrieb:Copilot nutzt sogar Arrays weil das wahrscheinlich schneller ist und vom Compiler einfacher referenziert werden kann.