338 lines
12 KiB
Plaintext
338 lines
12 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>
|
|
<span>Money: $@Session.Money</span>
|
|
</div>
|
|
</div>
|
|
<!-- Tool Frame -->
|
|
<div class="gridFrame">
|
|
<div>
|
|
<div><h2>Actions</h2></div>
|
|
@if (Debounce){
|
|
<button @onclick="train">@trainButtonText</button>
|
|
<button @onclick="predict">@predictButtonText</button>
|
|
}else{
|
|
<button disabled>@trainButtonText</button>
|
|
<button disabled>@predictButtonText</button>
|
|
}
|
|
<br/>
|
|
<div>
|
|
@if (Debounce){
|
|
<input placeholder="Stock Symbol [NVDA]" @bind="buyStockSymbol" />
|
|
<input placeholder="Stock Quantity [1.0]" @bind="buyStockQuantity" />
|
|
<button @onclick="buyStock">Buy Stock</button>
|
|
} else {
|
|
<input disabled placeholder="Stock Symbol [NVDA]" @bind="buyStockSymbol" />
|
|
<input disabled placeholder="Stock Quantity [1.0]" @bind="buyStockQuantity" />
|
|
<button disabled>Buy Stock</button>
|
|
}
|
|
</div>
|
|
<span>@resultError</span>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- AI Frame -->
|
|
@if (Session != null){
|
|
<div class="gridFrame">
|
|
<div>
|
|
<h2>Current Signal</h2>
|
|
</div>
|
|
@foreach (PurchasedStock cur in Session.TrackedStocks){
|
|
<div class="signalBlock">
|
|
<div>
|
|
<p style="text-align: center; font-weight: bold;">@cur.Symbol</p>
|
|
<p>Purchased Price: @cur.PurchasePrice</p>
|
|
<p>Purchased Quantity: @cur.Quantity</p>
|
|
<p>Purchased Date: @cur.PurchaseDate.ToString("M-dd-yyyy")</p>
|
|
@if (Debounce){
|
|
<button @onclick="async () => {await sellStock(cur);}">Sell All</button>
|
|
}else{
|
|
<button disabled>Sell All</button>
|
|
}
|
|
</div>
|
|
<div>
|
|
<span>-></span>
|
|
</div>
|
|
@if (cur.PredictedMovement == -1){
|
|
<div style="background-color: red;"><p style=>Sell</p></div>
|
|
} else if (cur.PredictedMovement == 1){
|
|
<div style="background-color: green;"><p>Buy</p></div>
|
|
} else{
|
|
<div style="background-color: #444;"><p>Hold</p></div>
|
|
}
|
|
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
</div>
|
|
|
|
@code {
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
/// Code Region
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
loginSession? Session = null;
|
|
|
|
// On Page Load
|
|
string PaymentKey = "";
|
|
protected override async Task OnInitializedAsync(){
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Login Stuff
|
|
string userName = "";
|
|
string passWord = "";
|
|
string loginError = "";
|
|
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 (string.IsNullOrEmpty(passwordhash)){
|
|
loginError = "no account found with that username";
|
|
return;
|
|
}
|
|
if (BCrypt.Verify( passWord, passwordhash )){ // If the password is valid
|
|
List<PurchasedStock>? stocks = JsonConvert.DeserializeObject<List<PurchasedStock>>( dbDriver.Get( dbPrefix + "Stocks" ) );
|
|
bool moneyLoaded = float.TryParse(dbDriver.Get( dbPrefix + "money" ), out float moneyResult);
|
|
Session = new loginSession(){
|
|
UserName = userName.ToLower(),
|
|
TrackedStocks = stocks != null ? stocks : new List<PurchasedStock>(),
|
|
Money = moneyLoaded ? moneyResult : 1000
|
|
};
|
|
(bool, string) result = PaymentProcessor.CreatePayment(Session.UserName);
|
|
if (!result.Item1){
|
|
resultError = result.Item2;
|
|
}
|
|
PaymentKey = result.Item2;
|
|
}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() ) );
|
|
dbDriver.Set( dbPrefix + "money", "1000" );
|
|
Session = new loginSession(){
|
|
UserName = userName.ToLower(),
|
|
TrackedStocks = new List<PurchasedStock>(),
|
|
Money = 1000
|
|
};
|
|
(bool, string) result = PaymentProcessor.CreatePayment(Session.UserName);
|
|
if (!result.Item1){
|
|
resultError = result.Item2;
|
|
}
|
|
PaymentKey = result.Item2;
|
|
}else{
|
|
loginError = "account is taken";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// AI Stuff
|
|
|
|
string trainButtonText = "Force Retrain AI";
|
|
string predictButtonText = "Predict AI";
|
|
string resultError = "";
|
|
bool Debounce = true;
|
|
|
|
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";
|
|
await Task.Delay(2000);
|
|
trainButtonText = "Train AI";
|
|
await Task.Delay(1);
|
|
Debounce = true;
|
|
});
|
|
thread.Start();
|
|
}
|
|
}
|
|
|
|
async Task predict(){
|
|
resultError = "";
|
|
if (Debounce && Session != null){
|
|
Debounce = false;
|
|
predictButtonText = "Do not refresh the page. The AI is predicting";
|
|
await Task.Delay(1);
|
|
List<Task> threadpool = new List<Task>();
|
|
foreach(PurchasedStock cur in Session.TrackedStocks){
|
|
Task thread = new Task(() => {
|
|
(string, int)Result = aiModule.PredictAI(cur.Symbol);
|
|
if (string.IsNullOrEmpty(Result.Item1)){
|
|
cur.PredictedMovement = Result.Item2;
|
|
}else{
|
|
resultError = Result.Item1;
|
|
}
|
|
Console.WriteLine("Received Signal [" + cur.Symbol + "] : " + cur.PredictedMovement);
|
|
});
|
|
thread.Start();
|
|
threadpool.Add(thread);
|
|
}
|
|
await Task.WhenAll(threadpool);
|
|
predictButtonText = "Predictions loaded";
|
|
await Task.Delay(2000);
|
|
predictButtonText = "Predict AI";
|
|
Debounce = true;
|
|
await Task.Delay(1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Stock Manipulation
|
|
|
|
string buyStockSymbol = "";
|
|
string buyStockQuantity = "";
|
|
async Task buyStock(){
|
|
if (Debounce && Session != null){
|
|
Debounce = false;
|
|
await Task.Delay(1);
|
|
|
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
|
// Try Parse the quantitiy input
|
|
bool success = float.TryParse(buyStockQuantity, out float QuantityResult);
|
|
if (!success){
|
|
resultError = "Quantity field is not a number";
|
|
Debounce = true;
|
|
await Task.Delay(1);
|
|
return;
|
|
}
|
|
|
|
// Get Stock Price
|
|
float stockPrice = aiModule.GetCurrentPrice( buyStockSymbol );
|
|
|
|
// Try Pay for the stock
|
|
(bool, string) result = PaymentProcessor.TryPayment(PaymentKey, QuantityResult * stockPrice);
|
|
if (!result.Item1){
|
|
resultError = result.Item2;
|
|
Debounce = true;
|
|
await Task.Delay(1);
|
|
return;
|
|
}
|
|
|
|
// Add the stock
|
|
Session.TrackedStocks.Add( new PurchasedStock(){
|
|
Symbol = buyStockSymbol.ToUpper(),
|
|
PurchasePrice = stockPrice,
|
|
Quantity = QuantityResult,
|
|
PurchaseDate = DateTime.Now
|
|
} );
|
|
dbDriver.Set( dbPrefix + "Stocks", Newtonsoft.Json.JsonConvert.SerializeObject(Session.TrackedStocks) );
|
|
|
|
// Reload the users money
|
|
bool moneyLoaded = float.TryParse(dbDriver.Get( dbPrefix + "money" ), out float moneyResult);
|
|
Session.Money = moneyLoaded ? moneyResult : 1000;
|
|
|
|
// Reset the Impodent Key
|
|
result = PaymentProcessor.CreatePayment(Session.UserName);
|
|
if (!result.Item1){
|
|
resultError = "[New payment session failed] : " + result.Item2;
|
|
Debounce = true;
|
|
await Task.Delay(1);
|
|
return;
|
|
}
|
|
PaymentKey = result.Item2;
|
|
Debounce = true;
|
|
await Task.Delay(1);
|
|
}
|
|
}
|
|
|
|
async Task sellStock(PurchasedStock stock){
|
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
|
if (Debounce && Session != null){
|
|
Debounce = false;
|
|
await Task.Delay(1);
|
|
|
|
// Get sell price
|
|
float sellPrice = stock.Quantity * aiModule.GetCurrentPrice( stock.Symbol );
|
|
|
|
// Try to sell the stock
|
|
(bool, string) result = PaymentProcessor.TrySell(PaymentKey, sellPrice);
|
|
if (!result.Item1){
|
|
resultError = result.Item2;
|
|
Debounce = true;
|
|
await Task.Delay(1);
|
|
return;
|
|
}
|
|
|
|
// Remove Stock
|
|
Session.TrackedStocks.Remove(stock);
|
|
dbDriver.Set( dbPrefix + "Stocks", Newtonsoft.Json.JsonConvert.SerializeObject(Session.TrackedStocks) );
|
|
|
|
// Reload the users money
|
|
bool moneyLoaded = float.TryParse(dbDriver.Get( dbPrefix + "money" ), out float moneyResult);
|
|
Session.Money = moneyLoaded ? moneyResult : 1000;
|
|
|
|
// Reset the Impodent Key
|
|
result = PaymentProcessor.CreatePayment(Session.UserName);
|
|
if (!result.Item1){
|
|
resultError = "[New payment session failed] : " + result.Item2;
|
|
Debounce = true;
|
|
await Task.Delay(1);
|
|
return;
|
|
}
|
|
PaymentKey = result.Item2;
|
|
|
|
Debounce = true;
|
|
await Task.Delay(1);
|
|
}
|
|
}
|
|
} |