Create a simulation to test 1 month of data in 30 mins
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
from datetime import datetime, timedelta
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import joblib
|
import joblib
|
||||||
@@ -13,13 +14,29 @@ def Predict():
|
|||||||
# Get the Symbol from ARGV
|
# Get the Symbol from ARGV
|
||||||
Symbol = sys.argv[1]
|
Symbol = sys.argv[1]
|
||||||
|
|
||||||
|
# get the number of days ago to run the simulation for
|
||||||
|
DaysBack = int(sys.argv[2])
|
||||||
|
|
||||||
|
print(f"Days back: {DaysBack}")
|
||||||
|
|
||||||
|
# calculate the time offsets
|
||||||
|
end_date = datetime.now() - timedelta(days=DaysBack)
|
||||||
|
start_date = end_date - timedelta(days=70)
|
||||||
|
|
||||||
|
# convert to string formats
|
||||||
|
start_str = start_date.strftime('%Y-%m-%d')
|
||||||
|
end_str = end_date.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
print(f"Start Date: {start_str}")
|
||||||
|
print(f"End Date: {end_str}")
|
||||||
|
|
||||||
# Define paths (consistent with your previous script)
|
# Define paths (consistent with your previous script)
|
||||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
DATA_DIR = os.path.join(SCRIPT_DIR, "data")
|
DATA_DIR = os.path.join(SCRIPT_DIR, "data")
|
||||||
MODEL_PATH = os.path.join(DATA_DIR, "model.keras")
|
MODEL_PATH = os.path.join(DATA_DIR, "model.keras")
|
||||||
|
|
||||||
# Pull 1 month of current data to make prediction against | for volatility 20
|
# Pull 1 month of current data to make prediction against | for volatility 20
|
||||||
df = yf.download(Symbol, period="2mo", auto_adjust=True)
|
df = yf.download(Symbol, start=start_str, end=end_str, auto_adjust=True, progress=False)
|
||||||
if not df.empty:
|
if not df.empty:
|
||||||
# Remove the horizontal ticker column
|
# Remove the horizontal ticker column
|
||||||
df.columns = df.columns.get_level_values(0)
|
df.columns = df.columns.get_level_values(0)
|
||||||
|
|||||||
@@ -78,10 +78,11 @@ def MakeFeatures(df):
|
|||||||
df.drop(col, axis=1, inplace=True)
|
df.drop(col, axis=1, inplace=True)
|
||||||
|
|
||||||
# Drop rows with null values
|
# Drop rows with null values
|
||||||
df.dropna(inplace=True)
|
feature_columns = [col for col in df.columns if col != 'Target_Close'] # Dont drop any Target_Close as we need this data for predictions
|
||||||
|
df.dropna(subset=feature_columns, inplace=True)
|
||||||
|
|
||||||
# Replace Infinity with 0 -> This fixes the AI mental breakdown
|
# Replace Infinity with 0 -> This fixes the AI mental breakdown
|
||||||
df = df.replace([np.inf, -np.inf], 0)
|
df.replace([np.inf, -np.inf], 0, inplace=True)
|
||||||
|
|
||||||
# Replace Infinity with 0 -> This fixes the AI mental breakdown
|
# Replace Infinity with 0 -> This fixes the AI mental breakdown
|
||||||
df['Volume_Chg'] = df['Volume_Chg'].replace([np.inf, -np.inf], 0)
|
df['Volume_Chg'] = df['Volume_Chg'].replace([np.inf, -np.inf], 0)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
@using Controllers.Payment
|
@using Controllers.Payment
|
||||||
|
@using Controllers.ProjectTest
|
||||||
@using Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments
|
@using Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
@@ -46,6 +47,11 @@
|
|||||||
<input placeholder="Stock Symbol [NVDA]" @bind="addStockSymbol" />
|
<input placeholder="Stock Symbol [NVDA]" @bind="addStockSymbol" />
|
||||||
<button @onclick="addStock">Add To Tracked Stocks</button>
|
<button @onclick="addStock">Add To Tracked Stocks</button>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
<div>
|
||||||
|
<button @onclick="RunTest">Run 1Mo Test</button>
|
||||||
|
<span>@TestResults</span>
|
||||||
|
</div>
|
||||||
<span>@resultError</span>
|
<span>@resultError</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -195,4 +201,13 @@
|
|||||||
string dbPrefix = $"[{userName.ToLower()}]:";
|
string dbPrefix = $"[{userName.ToLower()}]:";
|
||||||
dbDriver.Set(dbPrefix + "watched", JsonConvert.SerializeObject(Session.TrackedStocks) );
|
dbDriver.Set(dbPrefix + "watched", JsonConvert.SerializeObject(Session.TrackedStocks) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string TestResults = "";
|
||||||
|
async Task RunTest(){
|
||||||
|
D683_Project_Test tests = new D683_Project_Test(aiModule);
|
||||||
|
float score = await tests.Simulate();
|
||||||
|
TestResults = score.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -17,14 +17,17 @@ namespace Controllers.Automation {
|
|||||||
_paymentProcessor = PaymentProcessor;
|
_paymentProcessor = PaymentProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GlobalPredictAI() {
|
public void GlobalPredictAI(int DaysBefore = 0, bool testmode = false) {
|
||||||
|
|
||||||
// Start this process on a background thread so its non-blocking
|
// Start this process on a background thread so its non-blocking
|
||||||
Task thread = new Task(() => {
|
Task thread = new Task(() => {
|
||||||
|
|
||||||
// Load the userlist
|
// Load the userlist
|
||||||
List<string>? UserList = JsonConvert.DeserializeObject<List<string>>(_dbDriver.Get("Users"));
|
List<string> VerifiedUserList = new List<string>(){ "TESTMODE" };
|
||||||
List<string> VerifiedUserList = UserList != null ? UserList : new List<string>();
|
if (!testmode) {
|
||||||
|
List<string>? UserList = JsonConvert.DeserializeObject<List<string>>(_dbDriver.Get("Users"));
|
||||||
|
VerifiedUserList = UserList != null ? UserList : new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
// Process each request at the same time for speed improvement
|
// Process each request at the same time for speed improvement
|
||||||
Parallel.ForEach(VerifiedUserList, async (username) => {
|
Parallel.ForEach(VerifiedUserList, async (username) => {
|
||||||
@@ -40,7 +43,7 @@ namespace Controllers.Automation {
|
|||||||
|
|
||||||
// Predict the trend on a new thread
|
// Predict the trend on a new thread
|
||||||
Task thread = new Task(() => {
|
Task thread = new Task(() => {
|
||||||
(string, float)Result = _aiModule.PredictAI(cur.Symbol);
|
(string, float)Result = _aiModule.PredictAI(cur.Symbol, DaysBefore);
|
||||||
|
|
||||||
// If error log it
|
// If error log it
|
||||||
if (!string.IsNullOrEmpty(Result.Item1)){
|
if (!string.IsNullOrEmpty(Result.Item1)){
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
using Controllers.PythonInterop;
|
||||||
|
using Entities;
|
||||||
|
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||||
|
|
||||||
|
namespace Controllers.ProjectTest {
|
||||||
|
|
||||||
|
public class D683_Project_Test {
|
||||||
|
|
||||||
|
// TESTING Starting Money
|
||||||
|
float Money = 1000;
|
||||||
|
|
||||||
|
// TESTING WATCH STOCK LIST
|
||||||
|
List<Stock> TrackedStocks = new List<Stock>() {
|
||||||
|
new Stock(){ Symbol="NVDA" },
|
||||||
|
new Stock(){ Symbol="INTL" },
|
||||||
|
new Stock(){ Symbol="AAPL" },
|
||||||
|
new Stock(){ Symbol="SHOP" },
|
||||||
|
new Stock(){ Symbol="PANW" },
|
||||||
|
new Stock(){ Symbol="BBBY" },
|
||||||
|
new Stock(){ Symbol="REAL" },
|
||||||
|
new Stock(){ Symbol="W" },
|
||||||
|
new Stock(){ Symbol="ROKU" },
|
||||||
|
new Stock(){ Symbol="FUN" }
|
||||||
|
};
|
||||||
|
|
||||||
|
// TESTING STOCK HISTORY
|
||||||
|
List<PurchasedStock> StockHistory = new List<PurchasedStock>();
|
||||||
|
|
||||||
|
AIModule _aiModule;
|
||||||
|
public D683_Project_Test( AIModule aiModule ) {
|
||||||
|
_aiModule = aiModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<float> Simulate() {
|
||||||
|
float StartingMoney = Money;
|
||||||
|
// Run once for each day 30 days straight
|
||||||
|
for (int i=30; i>=0; i--) {
|
||||||
|
|
||||||
|
// Go through each watched stock and find the highest prediction
|
||||||
|
List<Task> threadpool = new List<Task>();
|
||||||
|
foreach(Stock cur in TrackedStocks) {
|
||||||
|
|
||||||
|
// Predict the trend on a new thread
|
||||||
|
Task thread = new Task(async () => {
|
||||||
|
(string, float)Result = _aiModule.PredictAI(cur.Symbol, i);
|
||||||
|
|
||||||
|
// 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 processes to finish
|
||||||
|
await Task.WhenAll( threadpool );
|
||||||
|
|
||||||
|
// Get the highest ranked
|
||||||
|
Stock HighestRanking = new Stock(){ Symbol="NVDA", Score = -400 }; // Just a placeholder incase an empty list comes through there is a fallback
|
||||||
|
foreach(Stock cur in TrackedStocks) {
|
||||||
|
if (HighestRanking.Score < cur.Score) {
|
||||||
|
HighestRanking = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sell all stocks
|
||||||
|
float totalSale = 0;
|
||||||
|
foreach(PurchasedStock cur in StockHistory) {
|
||||||
|
if (cur.Sold == false) {
|
||||||
|
// Get sell price
|
||||||
|
float sellPrice = cur.Quantity * _aiModule.GetCurrentPrice( cur.Symbol );
|
||||||
|
// Add up the total sale
|
||||||
|
totalSale += sellPrice;
|
||||||
|
// Mark as sold
|
||||||
|
cur.Sold = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Money += totalSale;
|
||||||
|
|
||||||
|
// Dont buy anything on the last run
|
||||||
|
if (i != 0) {
|
||||||
|
|
||||||
|
// Buy predicted stock
|
||||||
|
float stockPrice = _aiModule.GetCurrentPrice( HighestRanking.Symbol );
|
||||||
|
|
||||||
|
// Get max stocks user can purchase [ int cast truncates the decimal ]
|
||||||
|
int MaxQty = (int)( Money / stockPrice );
|
||||||
|
|
||||||
|
// Add the stock
|
||||||
|
StockHistory.Add( new PurchasedStock(){
|
||||||
|
Symbol = HighestRanking.Symbol.ToUpper(),
|
||||||
|
PurchasePrice = stockPrice,
|
||||||
|
Quantity = MaxQty,
|
||||||
|
} );
|
||||||
|
Money = Money - ( stockPrice * MaxQty );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a score [Bigger than 0 is money earned] or [Less than 0 is money lost]
|
||||||
|
return Money - StartingMoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,8 +27,8 @@ namespace Controllers.PythonInterop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return ( Error, Signal )
|
// Return ( Error, Signal )
|
||||||
public (string, float) PredictAI(string StockSymbol) {
|
public (string, float) PredictAI(string StockSymbol, int DataEndDaysAgo = 0) {
|
||||||
(bool, string) Success = PyProcess.RunPythonProcess(_PyPath, _ExecPath + "/aipredictor.py", returns: true, PyArgs: StockSymbol);
|
(bool, string) Success = PyProcess.RunPythonProcess(_PyPath, _ExecPath + "/aipredictor.py", returns: true, PyArgs: $"{StockSymbol} {DataEndDaysAgo}");
|
||||||
if (!Success.Item1) {
|
if (!Success.Item1) {
|
||||||
return (Success.Item2, 0);
|
return (Success.Item2, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user