Files
AI-Stock-Trader/WebServer/Components/Pages/Home.razor
T
2026-03-08 19:28:10 -07:00

281 lines
9.6 KiB
Plaintext

@page "/"
@using Controllers.Payment
@rendermode InteractiveServer
<PageTitle>Home</PageTitle>
<div class="main-area">
<!-- Login Frame -->
@if (Session == null){
<div class="gridFrame">
<div><h2>LOGIN</h2></div>
<div class="loginRow">
<div><span>username</span></div>
<input @bind-value="userName" type="text" />
</div>
<div class="loginRow">
<div><span>password</span></div>
<input @bind-value="passWord" type="password" />
</div>
<div class="loginRow">
<button @onclick="LoginSession">Login</button>
<button @onclick="registerSession">Register</button>
</div>
<div>
<span style="color: red;">@loginError</span>
</div>
</div>
<!-- User Frame -->
}else{
<div class="gridFrame">
<div><h2>Account</h2></div>
<span>UserName: @Session.UserName</span><br />
<div>
@foreach(PurchasedStock cur in Session.TrackedStocks){
<div>@cur.Symbol</div>
<div>@cur.Quantity</div>
<div>@cur.PurchasePrice</div>
<div>@cur.PurchaseDate.ToString("M-D-YYYY")</div>
}
</div>
</div>
<!-- Tool Frame -->
<div class="gridFrame">
<div>
<div><h2>Actions</h2></div>
@if (Debounce){
<button @onclick="pull">@pullButtonText</button>
<button @onclick="train">@trainButtonText</button>
<button @onclick="predict">@predictButtonText</button>
}else{
<button disabled>@pullButtonText</button>
<button disabled>@trainButtonText</button>
<button disabled>@predictButtonText</button>
}
<button @onclick="buyStock">Buy Stock</button>
<input placeholder="Stock Symbol [NVDA]" @bind="buyStockSymbol" />
<input placeholder="1.0" @bind="buyStockQuantity" />
<span>@resultError</span>
</div>
</div>
}
<!-- AI Frame -->
<div class="gridFrame">
<div>
<h2>Current Signal</h2>
</div>
@foreach (stockPredictionPair cur in predictions){
<div class="signalBlock">
<div>
<p>@cur.Symbol</p>
</div>
<div>
<span>-></span>
</div>
@if (cur.Movement == -1){
<div style="background-color: red;"><p style=>Sell</p></div>
} else if (cur.Movement == 1){
<div style="background-color: green;"><p>Buy</p></div>
} else{
<div style="background-color: #444;"><p>Hold</p></div>
}
</div>
}
</div>
</div>
@code {
// User Stuff
loginSession? Session = null;
// Login Stuff
string userName = "";
string passWord = "";
string loginError = "";
List<stockPredictionPair> predictions = new List<stockPredictionPair>(){
new stockPredictionPair(){ Symbol = "AAPL" },
new stockPredictionPair(){ Symbol = "AAPL" },
new stockPredictionPair(){ Symbol = "TTD" },
new stockPredictionPair(){ Symbol = "FUN" }
};
string PaymentKey = "";
protected override async Task OnInitializedAsync(){
(bool, string) result = PaymentProcessor.CreatePayment();
if (!result.Item1){
resultError = result.Item2;
}
PaymentKey = result.Item2;
}
async Task LoginSession(){
string dbPrefix = $"[{userName.ToLower()}]:"; // Set the DB prefix for the get and set
string passwordhash = dbDriver.Get( dbPrefix + "password" ); // Pull the password hash
if (BCrypt.Verify( passWord, passwordhash )){ // If the password is valid
List<PurchasedStock>? stocks = JsonConvert.DeserializeObject<List<PurchasedStock>>( dbDriver.Get( dbPrefix + "stock-data" ) );
Session = new loginSession(){
UserName = userName.ToLower(),
TrackedStocks = stocks != null ? stocks : new List<PurchasedStock>()
};
}else{
loginError = "wrong password";
}
}
async Task registerSession(){
string dbPrefix = $"[{userName.ToLower()}]:";
string passwordhash = dbDriver.Get( dbPrefix + "password" );
if (string.IsNullOrEmpty(passwordhash)){
dbDriver.Set( dbPrefix + "password", BCrypt.HashPassword( passWord, BCrypt.GenerateSalt() ) );
Session = new loginSession(){
UserName = userName.ToLower(),
TrackedStocks = new List<PurchasedStock>()
};
}else{
loginError = "account is taken";
}
}
// AI Stuff
string pullButtonText = "Pull Data";
string trainButtonText = "Train AI";
string predictButtonText = "Predict AI";
string resultError = "";
bool Debounce = true;
async Task pull(){
resultError = "";
if (Debounce){
Debounce = false;
pullButtonText = "Do not refresh the page. The data is pulling.";
await Task.Delay(1);
Task thread = new Task(async () => {
aiModule.PullAI();
pullButtonText = "Data pulled";
await InvokeAsync(StateHasChanged);
await Task.Delay(2000);
pullButtonText = "Pull Data";
await InvokeAsync(StateHasChanged);
Debounce = true;
});
thread.Start();
}
}
async Task train(){
resultError = "";
if (Debounce){
Debounce = false;
trainButtonText = "Do not refresh the page. The AI is training.";
await Task.Delay(1);
Task thread = new Task(async () => {
aiModule.TrainAI();
trainButtonText = "AI Trained";
StateHasChanged();
await Task.Delay(2000);
trainButtonText = "Train AI";
StateHasChanged();
Debounce = true;
});
thread.Start();
}
}
async Task predict(){
resultError = "";
if (Debounce){
Debounce = false;
predictButtonText = "Do not refresh the page. The AI is predicting";
await Task.Delay(1);
List<Task> threadpool = new List<Task>();
foreach(stockPredictionPair cur in predictions){
Task thread = new Task(() => {
(string, int)Result = aiModule.PredictAI(cur.Symbol);
if (string.IsNullOrEmpty(Result.Item1)){
cur.Movement = Result.Item2;
}else{
resultError = Result.Item1;
}
Console.WriteLine("Received Signal [" + cur.Symbol + "] : " + cur.Movement);
});
thread.Start();
threadpool.Add(thread);
}
await Task.WhenAll(threadpool);
predictButtonText = "Predictions loaded";
await Task.Delay(2000);
predictButtonText = "Predict AI";
Debounce = true;
}
}
// Stock Manipulation
string buyStockSymbol = "";
string buyStockQuantity = "";
float StockPrice = 0;
void buyStock(){
if (Session != null){
// Try Parse the quantitiy input
bool success = float.TryParse(buyStockQuantity, out float QuantityResult);
if (!success){
resultError = "Quantity field is not a number";
return;
}
// Try Pay for the stock
(bool, string) result = PaymentProcessor.TryPayment(PaymentKey, QuantityResult * StockPrice);
if (!result.Item1){
resultError = result.Item2;
return;
}
// Add the item
Session.TrackedStocks.Add( new PurchasedStock(){
Symbol = buyStockSymbol.ToLower(),
PurchasePrice = StockPrice,
Quantity = QuantityResult,
PurchaseDate = DateTime.Now
} );
// Reset the Impodent Key
result = PaymentProcessor.CreatePayment();
if (!result.Item1){
resultError = "[Payment suceeded but new payment session failed] : " + result.Item2;
return;
}
PaymentKey = result.Item2;
}
}
// Data Types
class stockPredictionPair {
public string Symbol { get; set; } = "";
public int Movement { get; set; } = 0;
}
class loginSession {
public string UserName { get; set; } = "";
public List<PurchasedStock> TrackedStocks { get; set; } = new List<PurchasedStock>();
}
class PurchasedStock {
public string Symbol { get; set; } = "";
public float PurchasePrice { get; set; } = 0;
public float Quantity { get; set; } = 0;
public DateTime PurchaseDate { get; set; } = DateTime.Now;
}
}