' --- ARCHITEKTUR: Referenztyp (Class) zur Vermeidung von Speicher-Kopierfehlern ---
Private Class Aktie
Public Property Name As String
Public Property StartKurs As Double
Public Property AktuellerKurs As Double
Public Property KursHistorie As List(Of Double)
Public Property HypeTicksRestlich As Integer
Public Property IstHype As Boolean
Public Property CrashTicksRestlich As Integer
Public Property IstCrash As Boolean
Public Property ChartPanel As Panel
Public Property KursLabel As Label
Public Property PendantName As String
' --- PARAMETER FÜR NATÜRLICHEN CHARTVERLAUF & IMPACT ---
Public Property Trend As Double
Public Property Volatilaet As Double
Public Property Phase As TrendPhase
Public Property PhasenTicksRestlich As Integer
Public Property StagnationsTicks As Integer
Public Property IstUltraHype As Boolean
End Class
Public Enum TrendPhase
Normal
Aufschwung
Hype
Abschwung
Crash
UltraHype
End Enum
Private Const SpielerStartKapital As Double = 1000.0
' --- GLOBALE VARIABLEN (SPIELER) ---
Private aktienListe As New Dictionary(Of String, Aktie)()
Private spielerGuthaben As Double = SpielerStartKapital
Private guthabenHistorie As New List(Of Double)()
Private spielerDepot As New Dictionary(Of String, Integer)()
Private einkaufsPreise As New Dictionary(Of String, Double)()
Private insolvenzRestPool As New Dictionary(Of String, Integer)()
' --- GLOBALE VARIABLEN (KI-GEGNER) ---
Private gegnerGuthaben As Double = SpielerStartKapital - 700
Private gegnerHistorie As New List(Of Double)()
Private gegnerDepot As New Dictionary(Of String, Integer)()
Private gegnerEinkaufsPreise As New Dictionary(Of String, Double)()
' --- MARKT-DATEN ---
Private aktienPool As New Dictionary(Of String, Integer)()
Private festeAktienKeys As New List(Of String)()
Private rand As New Random()
' --- BANK SYSTEM & REGULIERUNG ---
Private spielerKreditSchulden As Double = 0.0
Private Const MaxKreditLimit As Double = 25000.0
Private Const ZinsSatzProTick As Double = 0.001 ' 0.1% Zinsen pro Tick
' --- AUTO-TRADER ANTI-EXPLOIT PARAMETER ---
Private Const OrderGebuehrFlat As Double = 15.0 ' Fixe Gebühr pro Order
Private Const BrokerCourtageProzent As Double = 0.01 ' 1% variable Gebühr vom Transaktionsvolumen
Private Const MaxStandardTradeProTick As Integer = 5 ' Order-Slicing: Max. 5 Aktien pro Tick handelbar
' --- INITIALISIERUNG BEIM START ---
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Hardware-Beschleunigung & Pufferung aktivieren
Me.DoubleBuffered = True
Dim flags As Reflection.BindingFlags = Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.SetProperty
Dim pi As Reflection.PropertyInfo = GetType(Control).GetProperty("DoubleBuffered", flags)
' Chart-Historien vorbefüllen
For i As Integer = 1 To 8
guthabenHistorie.Add(spielerGuthaben)
gegnerHistorie.Add(gegnerGuthaben)
Next
For Each kvp In konfiguration
Dim name As String = kvp.Key
Dim startKurs As Double = kvp.Value.Item1
Dim pnl As Panel = kvp.Value.Item2
Dim lbl As Label = kvp.Value.Item3
Dim pendant As String = kvp.Value.Item4
Dim tempKurs As Double = startKurs
For i As Integer = 1 To 7
tempKurs *= (1.0 + (rand.NextDouble() * 0.04 - 0.02))
If tempKurs < 0.0 Then tempKurs = 0.0
neueAktie.KursHistorie.Add(Math.Round(tempKurs, 0))
Next
neueAktie.KursHistorie.Add(startKurs)
aktienListe(name) = neueAktie
Next
If pi IsNot Nothing Then
pi.SetValue(pnl_GuthabenChart, True, Nothing)
pi.SetValue(pnl_GegnerChart, True, Nothing)
For Each key In aktienListe.Keys
pi.SetValue(aktienListe(key).ChartPanel, True, Nothing)
Next
End If
festeAktienKeys = New List(Of String)(aktienListe.Keys)
If lstAktienUebersicht.Items.Count > 0 Then lstAktienUebersicht.SelectedIndex = 0
UpdateAnzeige()
End Sub
' --- SCHNELLER HANDEL (KLICK AUF PANEL) ---
Private Sub Panel_MouseClick(sender As Object, e As MouseEventArgs)
Dim pnl As Panel = DirectCast(sender, Panel)
If pnl.Tag Is Nothing Then Return
Dim aktienName As String = pnl.Tag.ToString()
Dim aktie As Aktie = aktienListe(aktienName)
If e.Button = MouseButtons.Left Then
If aktie.AktuellerKurs <= 0.0 Then
MessageBox.Show("Diese Aktie ist wertlos (0 €) und vom Handel ausgesetzt, bis sie sich erholt!", "Handelsstopp", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Return
End If
If aktienPool(aktienName) <= 0 Then
MessageBox.Show("Diese Aktie ist auf dem Weltmarkt komplett ausverkauft!", "Pool leer", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Return
End If
Dim gesamtKosten As Double = aktie.AktuellerKurs
If gesamtKosten <= spielerGuthaben Then
Dim alteMenge As Integer = spielerDepot(aktienName)
Dim alterEinkaufsPreis As Double = einkaufsPreise(aktienName)
Dim neueMenge As Integer = alteMenge + 1
Dim neueDurchschnittsKosten As Double = ((alteMenge * alterEinkaufsPreis) + gesamtKosten) / neueMenge
LoggeGuthaben()
BefuelleListBox()
UpdateAnzeige()
End If
ElseIf e.Button = MouseButtons.Right Then
If spielerDepot(aktienName) > 0 Then
Dim erloes As Double = aktie.AktuellerKurs
If aktie.AktuellerKurs <= 0.0 Then
insolvenzRestPool(aktienName) += 1
If insolvenzRestPool(aktienName) >= 100 Then
erloes = 1.0
insolvenzRestPool(aktienName) -= 100
End If
End If
spielerGuthaben += erloes
spielerDepot(aktienName) -= 1
If spielerDepot(aktienName) = 0 Then einkaufsPreise(aktienName) = 0.0
aktienPool(aktienName) += 1
aktie.Trend -= 0.005
LoggeGuthaben()
BefuelleListBox()
UpdateAnzeige()
End If
End If
End Sub
Private Sub LoggeGuthaben()
guthabenHistorie.Add(spielerGuthaben)
If guthabenHistorie.Count > 60 Then guthabenHistorie.RemoveAt(0)
pnl_GuthabenChart.Invalidate()
End Sub
Private Sub LoggeGegnerGuthaben()
gegnerHistorie.Add(gegnerGuthaben)
If gegnerHistorie.Count > 60 Then gegnerHistorie.RemoveAt(0)
pnl_GegnerChart.Invalidate()
End Sub
' --- RENDER ENGINE FÜR CHARTS ---
Private Sub Chart_Paint(sender As Object, e As PaintEventArgs)
Dim pnl As Panel = DirectCast(sender, Panel)
If pnl.Tag Is Nothing OrElse Not aktienListe.ContainsKey(pnl.Tag.ToString()) Then Return
Dim aktienName As String = pnl.Tag.ToString()
Dim historie As List(Of Double) = aktienListe(aktienName).KursHistorie
If historie.Count < 2 Then Return
Dim g As Graphics = e.Graphics
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
Dim maxWert As Double = historie.Max() * 1.05
Dim minWert As Double = historie.Min() * 0.95
Dim wertSpanne As Double = maxWert - minWert
If wertSpanne <= 0 Then wertSpanne = 1
Dim punkte As New List(Of PointF)()
Dim xSchritt As Single = pnl.Width / (historie.Count - 1)
For i As Integer = 0 To historie.Count - 1
Dim x As Single = i * xSchritt
Dim y As Single = CSng(pnl.Height - ((historie(i) - minWert) / wertSpanne * pnl.Height))
punkte.Add(New PointF(x, y))
Next
Using pen As New Pen(Color.White, 1.2!)
g.DrawLines(pen, punkte.ToArray())
End Using
End Sub
Private Sub GuthabenChart_Paint(sender As Object, e As PaintEventArgs)
If guthabenHistorie.Count < 2 Then Return
Dim pnl As Panel = DirectCast(sender, Panel)
Dim g As Graphics = e.Graphics
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
Dim randLinks As Single = 65.0!
Dim chartBreite As Single = pnl.Width - randLinks
Dim chartHoehe As Single = pnl.Height - 16.0!
Dim maxWert As Double = guthabenHistorie.Max()
Dim minWert As Double = guthabenHistorie.Min()
If maxWert = minWert Then
maxWert += 100
minWert -= 100
End If
Dim wertSpanne As Double = maxWert - minWert
Using achsenPen As New Pen(Color.FromArgb(80, Color.White), 1.0!)
g.DrawLine(achsenPen, randLinks, 5, randLinks, chartHoehe)
g.DrawLine(achsenPen, randLinks, chartHoehe, pnl.Width, chartHoehe)
End Using
Using textFont As New Font("Segoe UI", 8.0!, FontStyle.Regular)
Using textBrush As New SolidBrush(Color.Gold)
g.DrawString($"{maxWert:N0} €", textFont, textBrush, 2, 2)
Dim midWert As Double = minWert + (wertSpanne / 2)
g.DrawString($"{midWert:N0} €", textFont, textBrush, 2, (chartHoehe / 2) - 6)
g.DrawString($"{minWert:N0} €", textFont, textBrush, 2, chartHoehe - 12)
End Using
End Using
Dim punkte As New List(Of PointF)()
Dim xSchritt As Single = chartBreite / (guthabenHistorie.Count - 1)
For i As Integer = 0 To guthabenHistorie.Count - 1
Dim x As Single = randLinks + (i * xSchritt)
Dim y As Single = CSng(chartHoehe - ((guthabenHistorie(i) - minWert) / wertSpanne * (chartHoehe - 10)))
punkte.Add(New PointF(x, y))
Next
Using pen As New Pen(Color.Gold, 1.2!)
g.DrawLines(pen, punkte.ToArray())
End Using
End Sub
Private Sub GegnerChart_Paint(sender As Object, e As PaintEventArgs)
If gegnerHistorie.Count < 2 Then Return
Dim pnl As Panel = DirectCast(sender, Panel)
Dim g As Graphics = e.Graphics
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
Dim maxWert As Double = gegnerHistorie.Max()
Dim minWert As Double = gegnerHistorie.Min()
If maxWert = minWert Then
maxWert += 100
minWert -= 100
End If
Dim wertSpanne As Double = maxWert - minWert
If wertSpanne <= 0 Then wertSpanne = 1
Dim punkte As New List(Of PointF)()
Dim xSchritt As Single = pnl.Width / (gegnerHistorie.Count - 1)
For i As Integer = 0 To gegnerHistorie.Count - 1
Dim x As Single = i * xSchritt
Dim y As Single = CSng(pnl.Height - ((gegnerHistorie(i) - minWert) / wertSpanne * (pnl.Height - 10)))
If y < 5 Then y = 5
If y > pnl.Height - 5 Then y = pnl.Height - 5
punkte.Add(New PointF(x, y))
Next
Using pen As New Pen(Color.White, 1.2!)
g.DrawLines(pen, punkte.ToArray())
End Using
End Sub
' --- UI POOL FILLERS ---
Private Sub BefuelleListBox()
Dim vorherigeAuswahl As String = GetSelectedAktienName()
lstAktienUebersicht.Items.Clear()
For Each key In festeAktienKeys
Dim anzahl As Integer = spielerDepot(key)
If anzahl > 0 Then
Dim einkauf As Double = einkaufsPreise(key)
Dim aktuell As Double = aktienListe(key).AktuellerKurs
If aktuell > einkauf Then
lstAktienUebersicht.Items.Add($"{key} ({anzahl}) [Gewinn]")
ElseIf aktuell < einkauf Then
lstAktienUebersicht.Items.Add($"{key} ({anzahl}) [Verlust]")
Else
lstAktienUebersicht.Items.Add($"{key} ({anzahl}) [±0]")
End If
Else
lstAktienUebersicht.Items.Add($"{key} ({anzahl})")
End If
Next
If Not String.IsNullOrEmpty(vorherigeAuswahl) Then
For i As Integer = 0 To lstAktienUebersicht.Items.Count - 1
If lstAktienUebersicht.Items(i).ToString().StartsWith (vorherigeAuswahl & " (") Then
lstAktienUebersicht.SelectedIndex = i
Exit For
End If
Next
End If
End Sub
Private Sub BefuelleAutoTraderComboBox()
cmbAutoAktie.Items.Clear()
For Each key In festeAktienKeys
cmbAutoAktie.Items.Add(key)
Next
If cmbAutoAktie.Items.Count > 0 Then cmbAutoAktie.SelectedIndex = 0
End Sub
' --- ZENTRALER MARKT-TICK ---
Private Sub tmrMarkt_Tick(sender As Object, e As EventArgs) Handles tmrMarkt.Tick
' 1. Kreditzinsen berechnen
If spielerKreditSchulden > 0 Then
spielerKreditSchulden += spielerKreditSchulden * ZinsSatzProTick
spielerKreditSchulden = Math.Round(spielerKreditSchulden, 0)
End If
' 2. Aktien aktualisieren
For Each key In festeAktienKeys
Dim aktie As Aktie = aktienListe(key)
Dim vorherigerKurs As Double = aktie.AktuellerKurs
If aktie.PhasenTicksRestlich <= 0 Then
Dim wuerfel As Integer = rand.Next(1, 101)
Select Case aktie.Phase
Case TrendPhase.Normal
If wuerfel <= 20 Then
aktie.Phase = TrendPhase.Aufschwung
aktie.PhasenTicksRestlich = rand.Next(10, 20)
ElseIf wuerfel <= 40 Then
aktie.Phase = TrendPhase.Abschwung
aktie.PhasenTicksRestlich = rand.Next(10, 20)
Else
aktie.PhasenTicksRestlich = rand.Next(15, 30)
End If
Case TrendPhase.Aufschwung
If wuerfel <= 30 Then
aktie.Phase = TrendPhase.Hype
aktie.PhasenTicksRestlich = rand.Next(6, 12)
aktie.IstHype = True
ElseIf wuerfel <= 60 Then
aktie.Phase = TrendPhase.Normal
aktie.PhasenTicksRestlich = rand.Next(15, 25)
Else
aktie.PhasenTicksRestlich = rand.Next(8, 15)
End If
Case TrendPhase.Hype
aktie.IstHype = False
If wuerfel <= 75 Then
aktie.Phase = TrendPhase.Abschwung
aktie.PhasenTicksRestlich = rand.Next(8, 16)
Else
aktie.Phase = TrendPhase.Normal
aktie.PhasenTicksRestlich = rand.Next(15, 25)
End If
Case TrendPhase.Abschwung
If wuerfel <= 25 Then
aktie.Phase = TrendPhase.Crash
aktie.PhasenTicksRestlich = rand.Next(5, 10)
aktie.IstCrash = True
ElseIf wuerfel <= 60 Then
aktie.Phase = TrendPhase.Normal
aktie.PhasenTicksRestlich = rand.Next(15, 25)
Else
aktie.PhasenTicksRestlich = rand.Next(8, 15)
End If
Case TrendPhase.Crash
aktie.IstCrash = False
If wuerfel <= 40 Then
aktie.Phase = TrendPhase.Aufschwung
aktie.PhasenTicksRestlich = rand.Next(8, 15)
Else
aktie.Phase = TrendPhase.Normal
aktie.PhasenTicksRestlich = rand.Next(20, 35)
End If
Case TrendPhase.UltraHype
aktie.IstUltraHype = False
aktie.Phase = TrendPhase.Normal
aktie.PhasenTicksRestlich = rand.Next(15, 30)
End Select
End If
aktie.PhasenTicksRestlich -= 1
Select Case aktie.Phase
Case TrendPhase.Normal
aktie.Trend = (aktie.Trend * 0.75) + (rand.NextDouble() * 0.006 - 0.003)
Case TrendPhase.Aufschwung
aktie.Trend = (aktie.Trend * 0.85) + (rand.NextDouble() * 0.008)
Case TrendPhase.Hype
aktie.Trend = 0.025 + (rand.NextDouble() * 0.02)
aktie.HypeTicksRestlich = aktie.PhasenTicksRestlich
Case TrendPhase.Abschwung
aktie.Trend = (aktie.Trend * 0.85) - (rand.NextDouble() * 0.008)
Case TrendPhase.Crash
aktie.Trend = -0.035 - (rand.NextDouble() * 0.025)
aktie.CrashTicksRestlich = aktie.PhasenTicksRestlich
Case TrendPhase.UltraHype
aktie.Trend = 0.06 + (rand.NextDouble() * 0.04)
aktie.HypeTicksRestlich = aktie.PhasenTicksRestlich
End Select
Dim rauschen As Double = (rand.NextDouble() * 2.0 - 1.0) * aktie.Volatilaet
Dim aenderungprozent As Double = aktie.Trend + rauschen
If Not String.IsNullOrEmpty(aktie.PendantName) AndAlso aktienListe.ContainsKey(aktie.PendantName) Then
Dim pendantAktie As Aktie = aktienListe(aktie.PendantName)
If pendantAktie.Phase = TrendPhase.Hype Then
aenderungprozent -= (rand.NextDouble() * 0.03) + 0.01
ElseIf pendantAktie.Phase = TrendPhase.Crash Then
aenderungprozent += (rand.NextDouble() * 0.03) + 0.01
End If
End If
If aenderungprozent > 0.15 Then aenderungprozent = 0.15
If aenderungprozent < -0.15 Then aenderungprozent = -0.15
Dim neuerKurs As Double = aktie.AktuellerKurs * (1.0 + aenderungprozent)
If neuerKurs < 1.0 Then neuerKurs = 1.0
Dim gerundeterKurs As Double = Math.Round(neuerKurs, 0)
' --- FIX: EINFRIER- UND STAGNATIONSSCHUTZ ---
If gerundeterKurs = vorherigerKurs Then
aktie.StagnationsTicks += 1
If aktie.StagnationsTicks >= 6 Then
If rand.Next(1, 101) <= 20 Then
aktie.Phase = TrendPhase.UltraHype
aktie.PhasenTicksRestlich = rand.Next(15, 30)
aktie.IstUltraHype = True
aktie.Trend = 0.1
aktie.StagnationsTicks = 0
Else
aktie.Trend = If(rand.Next(0, 2) = 0, 0.03, -0.03)
End If
End If
Else
If aktie.StagnationsTicks > 0 Then aktie.StagnationsTicks -= 1
End If
aktie.AktuellerKurs = gerundeterKurs
aktie.KursHistorie.Add(aktie.AktuellerKurs)
If aktie.KursHistorie.Count > 60 Then aktie.KursHistorie.RemoveAt(0)
If aktie.Phase <> TrendPhase.UltraHype AndAlso aktie.Phase <> TrendPhase.Hype Then
aktie.Trend *= 0.95
End If
aktie.ChartPanel.Invalidate()
Next
' 3. KI verarbeiten
VerarbeiteGegnerKI()
' 4. Historie
guthabenHistorie.Add(spielerGuthaben)
If guthabenHistorie.Count > 60 Then guthabenHistorie.RemoveAt(0)
pnl_GuthabenChart.Invalidate()
' 5. AutoTrader
If chkAutoTrade.Checked Then PruefeAutoTrader()
' 6. UI
UpdateAnzeige()
End Sub
' --- KI-LOGIK (SKALIERT NACH LEVEL) ---
Private Sub VerarbeiteGegnerKI()
Dim spielerGesamtWert As Double = spielerGuthaben
For Each kvp In spielerDepot
If aktienListe.ContainsKey(kvp.Key) Then
spielerGesamtWert += kvp.Value * aktienListe(kvp.Key).AktuellerKurs
End If
Next
Dim gegnerGesamtWert As Double = gegnerGuthaben + BerechneGegnerDepotWert()
Dim stopLossSchwelle As Double = -0.15
Dim takeProfitSchwelle As Double = 0.25
Dim maxPortfolioAnteil As Double = 0.3
Dim kaufEinsatzFaktor As Double = 0.4
Dim mindestScoreFuerKauf As Double = 15.0
Dim bailoutChance As Integer = 0
Dim kiTypName As String = "Standard"
For Each aktienName In festeAktienKeys
Dim aktie As Aktie = aktienListe(aktienName)
Dim menge As Integer = gegnerDepot(aktienName)
If menge > 0 Then
Dim einkaufsPreis As Double = gegnerEinkaufsPreise(aktienName)
Dim gewinnProzent As Double = 0.0
If einkaufsPreis > 0 Then gewinnProzent = (aktie.AktuellerKurs - einkaufsPreis) / einkaufsPreis
Dim istImAufwindsRausch As Boolean = (aktie.Phase = TrendPhase.Hype OrElse aktie.Phase = TrendPhase.UltraHype)
Dim verkaufMenge As Integer = 0
Dim grund As String = ""
If aktie.AktuellerKurs <= 0.0 Then
grund = "TOTALVERLUST"
verkaufMenge = menge
ElseIf aktie.IstCrash OrElse gewinnProzent <= stopLossSchwelle Then
grund = If(aktie.IstCrash, "MARKT-CRASH", "TACTICAL STOP-LOSS")
verkaufMenge = menge
ElseIf istImAufwindsRausch AndAlso aktie.HypeTicksRestlich <= 1 Then
grund = "PEAK-PROFIT"
verkaufMenge = menge
ElseIf gewinnProzent >= takeProfitSchwelle AndAlso Not istImAufwindsRausch Then
grund = "TAKE-PROFIT"
verkaufMenge = CInt(Math.Ceiling(menge * If(RB_KiLvl3.Checked, 0.25, 0.5)))
End If
If verkaufMenge > 0 Then
Dim erloes As Double = verkaufMenge * aktie.AktuellerKurs
gegnerGuthaben += erloes
gegnerDepot(aktienName) -= verkaufMenge
aktienPool(aktienName) += verkaufMenge
Dim marktEinfluss As Double = (verkaufMenge * aktie.AktuellerKurs) / (gegnerGesamtWert + 1)
aktie.Trend -= Math.Min(marktEinfluss * 0.06, 0.05)
If gegnerDepot(aktienName) = 0 Then gegnerEinkaufsPreise(aktienName) = 0.0
Dim logEintrag As String = $"[{kiTypName}-VERKAUF] KI stößt {verkaufMenge}x {aktienName} zu {aktie.AktuellerKurs:N0} € ab | Grund: {grund}" & vbCrLf
If pnl_GegnerHistory.Lines.Length > 50 Then
pnl_GegnerHistory.Text = logEintrag & String.Join(vbCrLf, pnl_GegnerHistory.Lines.Take(40))
Else
pnl_GegnerHistory.Text = logEintrag & pnl_GegnerHistory.Text
End If
End If
End If
Next
Dim verfuegbaresBudget As Double = gegnerGuthaben * kaufEinsatzFaktor
Dim aktienScores As New List(Of Tuple(Of String, Double))()
For Each aktienName In festeAktienKeys
If aktienPool(aktienName) <= 0 Then Continue For
Dim aktie As Aktie = aktienListe(aktienName)
If aktie.AktuellerKurs <= 0.0 Then Continue For
Dim score As Double = 0.0
Select Case aktie.Phase
Case TrendPhase.UltraHype : score += 120.0
Case TrendPhase.Hype : score += 60.0
Case TrendPhase.Aufschwung : score += 30.0
Case TrendPhase.Abschwung : score -= 40.0
Case TrendPhase.Crash : score -= 90.0
End Select
If aktie.KursHistorie.Count >= 4 Then
Dim historischerKurs As Double = aktie.KursHistorie(aktie.KursHistorie.Count - 4)
If historischerKurs > 0 Then
Dim momentum As Double = (aktie.AktuellerKurs - historischerKurs) / historischerKurs
score += momentum * If(RB_KiLvl3.Checked, 250.0, 180.0)
End If
End If
aktienScores.Add(Tuple.Create(aktienName, score))
Next
For Each scoreEintrag In aktienScores
Dim aktienName As String = scoreEintrag.Item1
Dim score As Double = scoreEintrag.Item2
Dim aktie As Aktie = aktienListe(aktienName)
If score <= mindestScoreFuerKauf OrElse aktie.AktuellerKurs <= 0.0 Then Continue For
Dim verfuegbarImPool As Integer = aktienPool(aktienName)
If verfuegbarImPool <= 0 Then Continue For
Dim bereitsInvestiert As Double = gegnerDepot(aktienName) * aktie.AktuellerKurs
Dim portfolioAnteil As Double = bereitsInvestiert / If(gegnerGesamtWert = 0, 1, gegnerGesamtWert)
If portfolioAnteil >= maxPortfolioAnteil Then Continue For
Dim gewichteterEinsatz As Double = verfuegbaresBudget * (Math.Min(score, 100.0) / 100.0)
If gewichteterEinsatz > gegnerGuthaben Then gewichteterEinsatz = gegnerGuthaben
Dim mengeZuKaufen As Integer = CInt(Math.Floor(gewichteterEinsatz / aktie.AktuellerKurs))
If mengeZuKaufen > verfuegbarImPool Then mengeZuKaufen = verfuegbarImPool
If mengeZuKaufen > 0 Then
Dim alteMenge As Integer = gegnerDepot(aktienName)
Dim alterSchnitt As Double = gegnerEinkaufsPreise(aktienName)
Dim neueMenge As Integer = alteMenge + mengeZuKaufen
Dim neuerSchnitt As Double = ((alteMenge * alterSchnitt) + (mengeZuKaufen * aktie.AktuellerKurs)) / neueMenge
Dim marktEinfluss As Double = (mengeZuKaufen * aktie.AktuellerKurs) / (gegnerGesamtWert + 1)
aktie.Trend += Math.Min(marktEinfluss * 0.05, 0.04)
Dim logEintrag As String = $"[{kiTypName}-KAUF] KI kauft {mengeZuKaufen}x {aktienName} (Kurs: {aktie.AktuellerKurs:N0} €)" & vbCrLf
If pnl_GegnerHistory.Lines.Length > 50 Then
pnl_GegnerHistory.Text = logEintrag & String.Join(vbCrLf, pnl_GegnerHistory.Lines.Take(40))
Else
pnl_GegnerHistory.Text = logEintrag & pnl_GegnerHistory.Text
End If
verfuegbaresBudget -= (mengeZuKaufen * aktie.AktuellerKurs)
If verfuegbaresBudget <= aktie.AktuellerKurs OrElse gegnerGuthaben < 100 Then Exit For
End If
Next
If gegnerGuthaben < 300 AndAlso BerechneGegnerDepotWert() < 500 AndAlso bailoutChance > 0 Then
If rand.Next(1, 101) <= bailoutChance Then
Dim basisBonus As Double = rand.Next(1, 101)
gegnerGuthaben += basisBonus
Dim mtxGruende As String() = {
"Staatliches Hedgefonds-Bailout wegen Systemrelevanz bewilligt",
"Verlorene Krypto-Cold-Wallet im Serverraum erfolgreich wiedergefunden",
"Hochfrequenz-Arbitrage-Gewinne über Offshore-Zweigstelle realisiert",
"Heimliche Kapitalspritze durch ein asiatisches Investoren-Konsortium"
}
Dim gewaehlterGrund As String = mtxGruende(rand.Next(0, mtxGruende.Length))
Dim logEintrag As String = $"[BAILOUT] {kiTypName} fordert Liquidität! +{basisBonus:N0} € | Ursache: {gewaehlterGrund}" & vbCrLf
If pnl_GegnerHistory.Lines.Length > 50 Then
pnl_GegnerHistory.Text = logEintrag & String.Join(vbCrLf, pnl_GegnerHistory.Lines.Take(40))
Else
pnl_GegnerHistory.Text = logEintrag & pnl_GegnerHistory.Text
End If
End If
End If
If gegnerGuthaben < 0 Then gegnerGuthaben = 0
LoggeGegnerGuthaben()
End Sub
' --- ANTI-EXPLOIT AUTO-TRADER ---
Private Sub PruefeAutoTrader()
If cmbAutoAktie.SelectedIndex < 0 Then Return
Dim gewaehlteAktie As String = cmbAutoAktie.SelectedItem.ToString()
If Not aktienListe.ContainsKey(gewaehlteAktie) Then Return
Dim aktie As Aktie = aktienListe(gewaehlteAktie)
Dim anteileImBesitz As Integer = spielerDepot(gewaehlteAktie)
Dim maxAnzahl As Integer = Convert.ToInt32(numAutoAnzahl.Value)
Dim maxEinkaufswert As Double = Convert.ToDouble(numAutoEinkaufswert.Value)
Dim minVerkaufswert As Double = Convert.ToDouble(numAutoVerkaufswert.Value)
Dim depotAenderung As Boolean = False
' INKREMENTELLER KAUF (Order-Slicing & Gebühren)
If anteileImBesitz < maxAnzahl AndAlso aktie.AktuellerKurs <= maxEinkaufswert AndAlso aktie.AktuellerKurs > 0.0 Then
Dim gesamtBedarf As Integer = maxAnzahl - anteileImBesitz
Dim mengeZuKaufen As Integer = Math.Min(gesamtBedarf, MaxStandardTradeProTick)
If mengeZuKaufen > aktienPool(gewaehlteAktie) Then mengeZuKaufen = aktienPool(gewaehlteAktie)
If mengeZuKaufen > 0 Then
Dim reineKursKosten As Double = mengeZuKaufen * aktie.AktuellerKurs
Dim transaktionsGebuehren As Double = OrderGebuehrFlat + (reineKursKosten * BrokerCourtageProzent)
Dim gesamtKosten As Double = reineKursKosten + transaktionsGebuehren
If gesamtKosten > spielerGuthaben Then
mengeZuKaufen = CInt(Math.Floor((spielerGuthaben - OrderGebuehrFlat) / (aktie.AktuellerKurs * (1.0 + BrokerCourtageProzent))))
If mengeZuKaufen > MaxStandardTradeProTick Then mengeZuKaufen = MaxStandardTradeProTick
reineKursKosten = mengeZuKaufen * aktie.AktuellerKurs
transaktionsGebuehren = OrderGebuehrFlat + (reineKursKosten * BrokerCourtageProzent)
gesamtKosten = reineKursKosten + transaktionsGebuehren
End If
If mengeZuKaufen > 0 AndAlso gesamtKosten <= spielerGuthaben Then
Dim alteMenge As Integer = spielerDepot(gewaehlteAktie)
Dim alterEinkaufsPreis As Double = einkaufsPreise(gewaehlteAktie)
Dim neueMenge As Integer = alteMenge + mengeZuKaufen
Dim neueDurchschnittsKosten As Double = ((alteMenge * alterEinkaufsPreis) + gesamtKosten) / neueMenge
depotAenderung = True
LoggeGuthaben()
End If
End If
End If
' INKREMENTELLER VERKAUF
If anteileImBesitz > 0 AndAlso aktie.AktuellerKurs >= minVerkaufswert Then
Dim mengeZuVerkaufen As Integer = Math.Min(anteileImBesitz, MaxStandardTradeProTick)
Dim bruttoErloes As Double = mengeZuVerkaufen * aktie.AktuellerKurs
Dim transaktionsGebuehren As Double = OrderGebuehrFlat + (bruttoErloes * BrokerCourtageProzent)
Dim nettoErloes As Double = bruttoErloes - transaktionsGebuehren
If aktie.AktuellerKurs <= 0.0 Then
insolvenzRestPool(gewaehlteAktie) += mengeZuVerkaufen
Dim auszahlungsFaktor As Integer = Math.DivRem(insolvenzRestPool(gewaehlteAktie), 100, insolvenzRestPool(gewaehlteAktie))
nettoErloes = (auszahlungsFaktor * 1.0) - transaktionsGebuehren
End If
spielerGuthaben += nettoErloes
spielerDepot(gewaehlteAktie) -= mengeZuVerkaufen
If spielerDepot(gewaehlteAktie) = 0 Then einkaufsPreise(gewaehlteAktie) = 0.0
Private Function BerechneGegnerDepotWert() As Double
Dim gesamtWert As Double = 0.0
For Each kvp In gegnerDepot
Dim aktienName As String = kvp.Key
Dim menge As Integer = kvp.Value
If menge > 0 AndAlso aktienListe.ContainsKey(aktienName) Then
gesamtWert += menge * aktienListe(aktienName).AktuellerKurs
End If
Next
Return gesamtWert
End Function
' --- MANUELLE BUTTONS ---
Private Sub btnKaufen_Click(sender As Object, e As EventArgs) Handles btnKaufen.Click
Dim ausgewaehlteAktie As String = GetSelectedAktienName()
If String.IsNullOrEmpty(ausgewaehlteAktie) Then Return
Dim aktie As Aktie = aktienListe(ausgewaehlteAktie)
If aktie.AktuellerKurs <= 0.0 Then
MessageBox.Show("Diese Aktie ist momentan wertlos (0 €) und kann nicht gekauft werden!", "Handelsfehler", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Return
End If
Dim menge As Integer = Convert.ToInt32(numAnzahl.Value)
If aktienPool(ausgewaehlteAktie) <= 0 Then
MessageBox.Show("Diese Aktie ist auf dem Weltmarkt komplett ausverkauft!", "Handelsfehler", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Return
End If
If menge > aktienPool(ausgewaehlteAktie) Then menge = aktienPool(ausgewaehlteAktie)
Dim gesamtKosten As Double = menge * aktie.AktuellerKurs
If gesamtKosten <= spielerGuthaben Then
Dim alteMenge As Integer = spielerDepot(ausgewaehlteAktie)
Dim alterEinkaufsPreis As Double = einkaufsPreise(ausgewaehlteAktie)
Dim neueMenge As Integer = alteMenge + menge
Dim neueDurchschnittsKosten As Double = ((alteMenge * alterEinkaufsPreis) + gesamtKosten) / neueMenge
LoggeGuthaben()
BefuelleListBox()
UpdateAnzeige()
Application.DoEvents()
Else
MessageBox.Show("Nicht genug Euros für diesen Kauf!", "Handelsfehler", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Sub
Private Sub btnVerkaufen_Click(sender As Object, e As EventArgs) Handles btnVerkaufen.Click
Dim ausgewaehlteAktie As String = GetSelectedAktienName()
If String.IsNullOrEmpty(ausgewaehlteAktie) Then Return
Dim menge As Integer = Convert.ToInt32(numAnzahl.Value)
If menge <= spielerDepot(ausgewaehlteAktie) Then
Dim aktie As Aktie = aktienListe(ausgewaehlteAktie)
Dim erloes As Double = menge * aktie.AktuellerKurs
If aktie.AktuellerKurs <= 0.0 Then
insolvenzRestPool(ausgewaehlteAktie) += menge
Dim auszahlungsFaktor As Integer = Math.DivRem(insolvenzRestPool(ausgewaehlteAktie), 100, insolvenzRestPool(ausgewaehlteAktie))
erloes = auszahlungsFaktor * 1.0
End If
spielerGuthaben += erloes
spielerDepot(ausgewaehlteAktie) -= menge
If spielerDepot(ausgewaehlteAktie) = 0 Then einkaufsPreise(ausgewaehlteAktie) = 0.0
LoggeGuthaben()
BefuelleListBox()
UpdateAnzeige()
Application.DoEvents()
Else
MessageBox.Show("Du besitzt nicht genügend Anteile zum Verkaufen!", "Handelsfehler", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Sub
' --- BANK INTERAKTION ---
Private Sub btnKreditAufnehmen_Click(sender As Object, e As EventArgs) Handles btnKreditAufnehmen.Click
Dim gewuenschterKredit As Double = Convert.ToDouble(numBankKredit.Value)
If (spielerKreditSchulden + gewuenschterKredit) <= MaxKreditLimit Then
spielerKreditSchulden += gewuenschterKredit
spielerGuthaben += gewuenschterKredit
LoggeGuthaben()
UpdateAnzeige()
Else
MessageBox.Show($"Die Bank lehnt ab! Dein maximaler Kreditrahmen von {MaxKreditLimit:N0} € ist überschritten.", "Kreditlimit", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Sub
Private Sub btnKreditZurueckzahlen_Click(sender As Object, e As EventArgs) Handles btnKreditZurueckzahlen.Click
If spielerKreditSchulden <= 0 Then
MessageBox.Show("Du hast aktuell keine offenen Schulden bei der Bank.", "Keine Schulden", MessageBoxButtons.OK, MessageBoxIcon.Information)
Return
End If
Dim gewuenschteTilgung As Double = Convert.ToDouble(numBankTilgung.Value)
Dim tilgungsBetrag As Double = Math.Min(gewuenschteTilgung, spielerKreditSchulden)
If spielerGuthaben >= tilgungsBetrag Then
spielerGuthaben -= tilgungsBetrag
spielerKreditSchulden -= tilgungsBetrag
LoggeGuthaben()
UpdateAnzeige()
Else
MessageBox.Show($"Du hast nicht genug Bargeld auf dem Konto, um die Tilgung von {tilgungsBetrag:N0} € zu leisten!", "Mangelnde Liquidität", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End If
End Sub
For Each key In festeAktienKeys
Dim aktie As Aktie = aktienListe(key)
Dim poolMenge As Integer = aktienPool(key)
If aktie.Phase = TrendPhase.UltraHype Then
aktie.KursLabel.Text = $"{key}: {aktie.AktuellerKurs.ToString("#,##0")} €" & vbNewLine & "[UNDERTAKER!]" & vbNewLine & $"(Pool: {poolMenge}/100)"
aktie.KursLabel.ForeColor = Color.Magenta
aktie.ChartPanel.BackColor = Color.Purple
ElseIf aktie.Phase = TrendPhase.Hype Then
aktie.KursLabel.Text = $"{key}: {aktie.AktuellerKurs.ToString("#,##0")} €" & vbNewLine & "[HYPE!]" & vbNewLine & $"(Pool: {poolMenge}/100)"
aktie.KursLabel.ForeColor = Color.LimeGreen
aktie.ChartPanel.BackColor = Color.DarkGreen
ElseIf aktie.Phase = TrendPhase.Crash Then
If aktie.AktuellerKurs <= 0.0 Then
aktie.KursLabel.Text = $"{key}: INTERNATIONALE INSOLVENZ" & vbNewLine & "[WERTVERFALL / 0 €]" & vbNewLine & $"(Pool: {poolMenge}/100)"
Else
aktie.KursLabel.Text = $"{key}: {aktie.AktuellerKurs.ToString("#,##0")} €" & vbNewLine & "[CRASH!]" & vbNewLine & $"(Pool: {poolMenge}/100)"
End If
aktie.KursLabel.ForeColor = Color.Red
aktie.ChartPanel.BackColor = Color.DarkRed
Else
If aktie.AktuellerKurs <= 0.0 Then
aktie.KursLabel.Text = $"{key}: 0 €" & vbNewLine & "[LIQUIDATION / INSOLVENZ]" & vbNewLine & $"(Pool: {poolMenge}/100)"
aktie.KursLabel.ForeColor = Color.DarkGray
aktie.ChartPanel.BackColor = Color.FromArgb(20, 20, 22)
Else
aktie.KursLabel.Text = $"{key}: {aktie.AktuellerKurs.ToString("#,##0")} €" & vbNewLine & $"(Pool: {poolMenge}/100)"
aktie.KursLabel.ForeColor = Color.White
aktie.ChartPanel.BackColor = Color.FromArgb(45, 45, 48)
End If
End If
Next
Dim ausgewaehlteAktie As String = GetSelectedAktienName()
If Not String.IsNullOrEmpty(ausgewaehlteAktie) Then
Dim besitzAnzahl As Integer = spielerDepot(ausgewaehlteAktie)
Dim aktuellerKurs As Double = aktienListe(ausgewaehlteAktie).AktuellerKurs
Dim einkauf As Double = einkaufsPreise(ausgewaehlteAktie)
lblDepotInfo.Text = $"Besitz: {besitzAnzahl} Anteile" & vbCrLf &
$"Ø-Einkauf: {einkauf:N0} Euros" & vbCrLf &
$"Wert: {besitzAnzahl * aktuellerKurs:N0} Euros"
End If
End Sub
Private Sub lstAktienUebersicht_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstAktienUebersicht.SelectedIndexChanged
Dim ausgewaehlteAktie As String = GetSelectedAktienName()
If String.IsNullOrEmpty(ausgewaehlteAktie) Then Return
If cmbAutoAktie.SelectedItem IsNot Nothing AndAlso cmbAutoAktie.SelectedItem.ToString() <> ausgewaehlteAktie Then
cmbAutoAktie.SelectedItem = ausgewaehlteAktie
End If
UpdateAnzeige()
End Sub
Private Sub cmbAutoAktie_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbAutoAktie.SelectedIndexChanged
If cmbAutoAktie.SelectedIndex < 0 Then Return
Dim gewaehlteAktie As String = cmbAutoAktie.SelectedItem.ToString()
For i As Integer = 1 To 16
Dim lbl As Label = DirectCast(Me.Controls.Find("NamePan_" & i, True).FirstOrDefault(), Label)
If lbl IsNot Nothing Then
If lbl.Text = gewaehlteAktie Then
lbl.ForeColor = Color.LimeGreen
Else
lbl.ForeColor = Color.Yellow
End If
End If
Next
For i As Integer = 0 To lstAktienUebersicht.Items.Count - 1
If lstAktienUebersicht.Items(i).ToString().StartsWith (gewaehlteAktie & " (") Then
If lstAktienUebersicht.SelectedIndex <> i Then lstAktienUebersicht.SelectedIndex = i
Exit For
End If
Next
End Sub
Private Function GetSelectedAktienName() As String
If lstAktienUebersicht.SelectedIndex < 0 Then Return String.Empty
Dim roherEintrag As String = lstAktienUebersicht.SelectedItem.ToString()
If roherEintrag.Contains(" (") Then
Return roherEintrag.Substring(0, roherEintrag.IndexOf(" (")).Trim()
End If
Return roherEintrag
End Function
Private Sub GameSpeedBar_Scroll(sender As Object, e As EventArgs) Handles GameSpeedBar.Scroll
Dim intervalle() As Integer = {5000, 2000, 1500, 1250, 750, 500, 250, 150, 100, 50}
Dim index As Integer = GameSpeedBar.Value - 1
If index >= 0 AndAlso index < intervalle.Length Then
tmrMarkt.Interval = intervalle(index)
End If
End Sub
End Class
[S] User mit Trading/Börsen Erfahrung (Daytrader) 05/21/2016 - Trading - 2 Replies Hallo, da ich mich gerne mit der Börse beschäftigen möchte, würde ich nach Usern suchen, die sich mit dem Traden, der Börse und allg. Charts (Dax etc) beschäftigen.
Explizit suche ich nach Usern die Daytraden und auch gewisse Erfahrung mit sich bringen.
Über die Bezahlung etc kann man sich via PM austauschen
[S] Minecraft Börsen Plugin 12/13/2014 - Minecraft - 3 Replies Gibt es sowas? Einfach das es zufällig die Börse ändert und man Aktien kaufen/verkaufen kann.
Wie halt einfach eine echte Börse
Börsen Spiel 10/25/2013 - Off Topic - 11 Replies Hiho,
kennt jemand ein gutes Börsen Spiel wo es auch viele Mitspieler gibt? Gerne auch als App.
Ps. Sollte f2p sein