Start pulling AI out of the UI and into the background service
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
@using Controllers.Payment
|
@using Controllers.Payment
|
||||||
|
@using Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
<PageTitle>Home</PageTitle>
|
<PageTitle>Home</PageTitle>
|
||||||
@@ -36,28 +37,14 @@
|
|||||||
<span>Money: $@Session.Money</span>
|
<span>Money: $@Session.Money</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tool Frame -->
|
<!-- Tool Frame -->
|
||||||
<div class="gridFrame">
|
<div class="gridFrame">
|
||||||
<div>
|
<div>
|
||||||
<div><h2>Actions</h2></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>
|
<div>
|
||||||
@if (Debounce){
|
<input placeholder="Stock Symbol [NVDA]" @bind="addStockSymbol" />
|
||||||
<input placeholder="Stock Symbol [NVDA]" @bind="buyStockSymbol" />
|
<button @onclick="addStock">Add To Tracked Stocks</button>
|
||||||
<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>
|
</div>
|
||||||
<span>@resultError</span>
|
<span>@resultError</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -66,36 +53,34 @@
|
|||||||
|
|
||||||
<!-- AI Frame -->
|
<!-- AI Frame -->
|
||||||
@if (Session != null){
|
@if (Session != null){
|
||||||
<div class="gridFrame">
|
<div>
|
||||||
<div>
|
<!-- Tracked Stocks -->
|
||||||
<h2>Current Signal</h2>
|
<div class="gridFrame">
|
||||||
</div>
|
<div>
|
||||||
@foreach (PurchasedStock cur in Session.TrackedStocks){
|
<h2>Current Signal</h2>
|
||||||
<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>
|
||||||
}
|
@foreach (Stock cur in Session.TrackedStocks){
|
||||||
|
<div class="signalBlock">
|
||||||
|
<p style="text-align: center; font-weight: bold;">@cur.Symbol</p>
|
||||||
|
<p>AI Predicted Score: @cur.Score</p>
|
||||||
|
<button @onclick="async () => {await removeStock(cur);}">Remove</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<!-- Trade History -->
|
||||||
|
<div class="gridFrame">
|
||||||
|
<div>
|
||||||
|
<h2>Trade History</h2>
|
||||||
|
</div>
|
||||||
|
@foreach (PurchasedStock cur in Session.TradeHistory){
|
||||||
|
<div class="signalBlock">
|
||||||
|
<p style="text-align: center; font-weight: bold;">@cur.Symbol</p>
|
||||||
|
<p>Purchased Quantity: @cur.Quantity</p>
|
||||||
|
<p>Purchased Price: @cur.PurchasePrice</p>
|
||||||
|
<p>Sell Price: @cur.PurchasePrice</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,16 +93,8 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
loginSession? Session = null;
|
loginSession? Session = null;
|
||||||
|
string resultError = "";
|
||||||
// On Page Load
|
|
||||||
string PaymentKey = "";
|
|
||||||
protected override async Task OnInitializedAsync(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -126,213 +103,96 @@
|
|||||||
string passWord = "";
|
string passWord = "";
|
||||||
string loginError = "";
|
string loginError = "";
|
||||||
async Task LoginSession(){
|
async Task LoginSession(){
|
||||||
string dbPrefix = $"[{userName.ToLower()}]:"; // Set the DB prefix for the get and set
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
||||||
string passwordhash = dbDriver.Get( dbPrefix + "password" ); // Pull the password hash
|
|
||||||
|
// Check if user already exists
|
||||||
|
string passwordhash = dbDriver.Get( dbPrefix + "password" );
|
||||||
if (string.IsNullOrEmpty(passwordhash)){
|
if (string.IsNullOrEmpty(passwordhash)){
|
||||||
loginError = "no account found with that username";
|
loginError = "no account found with that username";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (BCrypt.Verify( passWord, passwordhash )){ // If the password is valid
|
|
||||||
List<PurchasedStock>? stocks = JsonConvert.DeserializeObject<List<PurchasedStock>>( dbDriver.Get( dbPrefix + "Stocks" ) );
|
// Check the password is valid
|
||||||
bool moneyLoaded = float.TryParse(dbDriver.Get( dbPrefix + "money" ), out float moneyResult);
|
if (!BCrypt.Verify( passWord, passwordhash )){
|
||||||
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";
|
loginError = "wrong password";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the users account
|
||||||
|
List<PurchasedStock>? history = JsonConvert.DeserializeObject<List<PurchasedStock>>( dbDriver.Get( dbPrefix + "history" ) );
|
||||||
|
List<Stock>? stocks = JsonConvert.DeserializeObject<List<Stock>>( dbDriver.Get( dbPrefix + "watched" ) );
|
||||||
|
bool moneyLoaded = float.TryParse(dbDriver.Get( dbPrefix + "money" ), out float moneyResult);
|
||||||
|
Session = new loginSession(){
|
||||||
|
UserName = userName.ToLower(),
|
||||||
|
TradeHistory = history != null ? history : new List<PurchasedStock>(),
|
||||||
|
TrackedStocks = stocks != null ? stocks : new List<Stock>(),
|
||||||
|
Money = moneyLoaded ? moneyResult : 1000
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task registerSession(){
|
async Task registerSession(){
|
||||||
string dbPrefix = $"[{userName.ToLower()}]:";
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
||||||
|
|
||||||
|
// Check if user already exists
|
||||||
string passwordhash = dbDriver.Get( dbPrefix + "password" );
|
string passwordhash = dbDriver.Get( dbPrefix + "password" );
|
||||||
if (string.IsNullOrEmpty(passwordhash)){
|
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";
|
loginError = "account is taken";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create User Object on the database
|
||||||
|
dbDriver.Set( dbPrefix + "password", BCrypt.HashPassword( passWord, BCrypt.GenerateSalt() ) );
|
||||||
|
dbDriver.Set( dbPrefix + "money", "1000" );
|
||||||
|
Session = new loginSession(){
|
||||||
|
UserName = userName.ToLower(),
|
||||||
|
TradeHistory = new List<PurchasedStock>(),
|
||||||
|
TrackedStocks = new List<Stock>(),
|
||||||
|
Money = 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add the users to a global table for automation
|
||||||
|
List<string>? Users = JsonConvert.DeserializeObject<List<string>>( dbDriver.Get( "Users" ) );
|
||||||
|
List<string> verifiedUsers = Users != null ? Users : new List<string>();
|
||||||
|
verifiedUsers.Add(userName.ToLower());
|
||||||
|
dbDriver.Set( "Users", JsonConvert.SerializeObject(verifiedUsers) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string addStockSymbol = "";
|
||||||
|
async Task addStock(){
|
||||||
|
|
||||||
|
// Make sure a session exists
|
||||||
|
if (Session == null){
|
||||||
// AI Stuff
|
return;
|
||||||
|
|
||||||
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(){
|
// Add a tracked stock to the users account
|
||||||
resultError = "";
|
Session.TrackedStocks.Add(new Stock(){
|
||||||
if (Debounce && Session != null){
|
Symbol = addStockSymbol.ToUpper()
|
||||||
Debounce = false;
|
});
|
||||||
predictButtonText = "Do not refresh the page. The AI is predicting";
|
|
||||||
await Task.Delay(1);
|
// Save the users account
|
||||||
List<Task> threadpool = new List<Task>();
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
||||||
foreach(PurchasedStock cur in Session.TrackedStocks){
|
dbDriver.Set(dbPrefix + "watched", JsonConvert.SerializeObject(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async Task removeStock(Stock stock){
|
||||||
|
|
||||||
|
// Make sure a session exists
|
||||||
|
if (Session == null){
|
||||||
// Stock Manipulation
|
return;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Remove the stock
|
||||||
|
Session.TrackedStocks.Remove(stock);
|
||||||
|
|
||||||
async Task sellStock(PurchasedStock stock){
|
// Save the users account
|
||||||
string dbPrefix = $"[{userName.ToLower()}]:";
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
||||||
if (Debounce && Session != null){
|
dbDriver.Set(dbPrefix + "watched", JsonConvert.SerializeObject(Session.TrackedStocks) );
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
using Controllers.DataBase;
|
||||||
|
using Entities;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Controllers.PythonInterop {
|
||||||
|
|
||||||
|
public class Automation {
|
||||||
|
|
||||||
|
AIModule _aiModule;
|
||||||
|
DbDriver _dbDriver;
|
||||||
|
public Automation(AIModule aiModule, DbDriver dbDriver) {
|
||||||
|
_aiModule = aiModule;
|
||||||
|
_dbDriver = dbDriver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GlobalPredictAI() {
|
||||||
|
|
||||||
|
// Start this process on a background thread so its non-blocking
|
||||||
|
Task thread = new Task(async () => {
|
||||||
|
|
||||||
|
// Load the userlist
|
||||||
|
List<string>? UserList = JsonConvert.DeserializeObject<List<string>>(_dbDriver.Get("Users"));
|
||||||
|
List<string> VerifiedUserList = UserList != null ? UserList : new List<string>();
|
||||||
|
|
||||||
|
// Process each request at the same time for speed improvement
|
||||||
|
Parallel.ForEach(VerifiedUserList, async (username) => {
|
||||||
|
string dbPrefix = $"[{username.ToLower()}]:";
|
||||||
|
|
||||||
|
// Load the Tracked stocks for each user
|
||||||
|
List<Stock>? TrackedStocks = JsonConvert.DeserializeObject<List<Stock>>( _dbDriver.Get( dbPrefix + "watched" ) );
|
||||||
|
List<Stock> VerifiedTrackedStocks = TrackedStocks != null ? TrackedStocks : new List<Stock>();
|
||||||
|
|
||||||
|
// Go through each stock
|
||||||
|
List<Task> threadpool = new List<Task>();
|
||||||
|
foreach(Stock cur in VerifiedTrackedStocks) {
|
||||||
|
|
||||||
|
// Predict the trend on a new thread
|
||||||
|
Task thread = new Task(() => {
|
||||||
|
(string, float)Result = _aiModule.PredictAI(cur.Symbol);
|
||||||
|
|
||||||
|
// If error log it
|
||||||
|
if (!string.IsNullOrEmpty(Result.Item1)){
|
||||||
|
Console.WriteLine(Result.Item1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the score to the users tracked stocks
|
||||||
|
cur.Score = Result.Item2;
|
||||||
|
});
|
||||||
|
thread.Start();
|
||||||
|
threadpool.Add(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all the threads to finish
|
||||||
|
await Task.WhenAll(threadpool);
|
||||||
|
|
||||||
|
// Process Stocks -> Buy Sell Hold / Based on the global data from earlier
|
||||||
|
|
||||||
|
// Save the new scores to the database for reference from the UI
|
||||||
|
_dbDriver.Set( dbPrefix + "watched", JsonConvert.SerializeObject( VerifiedTrackedStocks ) );
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
thread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GlobalTrainAI(){
|
||||||
|
Task thread = new Task(async () => {
|
||||||
|
_aiModule.TrainAI();
|
||||||
|
});
|
||||||
|
thread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sellStock(PurchasedStock stock){
|
||||||
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
||||||
|
if (Session != null){
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Stock
|
||||||
|
Session.TradeHistory.Remove(stock);
|
||||||
|
dbDriver.Set( dbPrefix + "Stocks", Newtonsoft.Json.JsonConvert.SerializeObject(Session.TradeHistory) );
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PaymentKey = result.Item2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void buyStock(string StockSymbol){
|
||||||
|
if (Session != null){
|
||||||
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
||||||
|
|
||||||
|
// Try Parse the quantitiy input
|
||||||
|
// Get the max quantity that I can Afford
|
||||||
|
float QuantityResult = 0;
|
||||||
|
|
||||||
|
// Get Stock Price
|
||||||
|
float stockPrice = aiModule.GetCurrentPrice( StockSymbol );
|
||||||
|
|
||||||
|
// Try Pay for the stock
|
||||||
|
(bool, string) result = PaymentProcessor.TryPayment(PaymentKey, QuantityResult * stockPrice);
|
||||||
|
if (!result.Item1){
|
||||||
|
resultError = result.Item2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the stock
|
||||||
|
Session.TradeHistory.Add( new PurchasedStock(){
|
||||||
|
Symbol = StockSymbol.ToUpper(),
|
||||||
|
PurchasePrice = stockPrice,
|
||||||
|
Quantity = QuantityResult,
|
||||||
|
} );
|
||||||
|
dbDriver.Set( dbPrefix + "Stocks", Newtonsoft.Json.JsonConvert.SerializeObject(Session.TradeHistory) );
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PaymentKey = result.Item2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,8 @@ namespace Entities {
|
|||||||
class loginSession {
|
class loginSession {
|
||||||
public string UserName { get; set; } = "";
|
public string UserName { get; set; } = "";
|
||||||
public float Money { get; set; } = 0;
|
public float Money { get; set; } = 0;
|
||||||
public List<PurchasedStock> TrackedStocks { get; set; } = new List<PurchasedStock>();
|
public List<Stock> TrackedStocks { get; set; } = new List<Stock>();
|
||||||
|
public List<PurchasedStock> TradeHistory { get; set; } = new List<PurchasedStock>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,9 @@ namespace Entities {
|
|||||||
|
|
||||||
class PurchasedStock {
|
class PurchasedStock {
|
||||||
public string Symbol { get; set; } = "";
|
public string Symbol { get; set; } = "";
|
||||||
public float PurchasePrice { get; set; } = 0;
|
|
||||||
public float Quantity { get; set; } = 0;
|
public float Quantity { get; set; } = 0;
|
||||||
public DateTime PurchaseDate { get; set; } = DateTime.Now;
|
public float PurchasePrice { get; set; } = 0;
|
||||||
public int PredictedMovement { get; set; } = 0;
|
public float SellPrice { get; set; } = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Entities {
|
||||||
|
|
||||||
|
class Stock {
|
||||||
|
public string Symbol { get; set; } = "";
|
||||||
|
public float Score { get; set; } = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user