Module:BassaridMarketActivity: Difference between revisions

From MicrasWiki
Jump to navigationJump to search
NewZimiaGov (talk | contribs)
No edit summary
Tag: Manual revert
NewZimiaGov (talk | contribs)
No edit summary
Line 1: Line 1:
---------------------------------------------------------
-- Module: BassaridiaDailyInvestorTable
-- Generates a daily table of investor stock activity
-- and associated reasons for increases/decreases.
--
-- Each day:
--  • A unique random seed is derived from the current
--    year and the day of the year (e.g. 2024 * 1000 + 45).
--  • Every cell (stocks, value, reasons) auto-updates
--    but remains stable for that particular day.
---------------------------------------------------------
local p = {}
local p = {}


---------------------------------------------------------
-- 1. Calendar Function
--    Returns date in PSSC terms + numeric dayOfMonth, month
---------------------------------------------------------
local function getCurrentDate()
local function getCurrentDate()
     local startDate = os.time({year = 1999, month = 8, day = 6})
     local startDate = os.time({year = 1999, month = 8, day = 6})
Line 25: Line 41:
     end
     end


     return string.format("%d/%d/%d [[PSSC]]", dayOfMonth, month, psscYear), dayOfMonth, month
     local dateString = string.format("%d/%d/%d [[PSSC]]", dayOfMonth, month, psscYear)
    return dateString, dayOfMonth, month
end
end


-- Initial figures for Regional Investors
---------------------------------------------------------
-- 2. Investor Data
---------------------------------------------------------
local investors = {
local investors = {
     {name = "Vaeringheim Regional Investor", stocks = 17424},
     {name = "Vaeringheim Regional Investor", stocks = 17424},
     {name = "Alpazkigz Regional Investor", stocks = 16214},
     {name = "Alpazkigz Regional Investor",   stocks = 16214},
     {name = "Odiferia Regional Investor", stocks = 14718},
     {name = "Odiferia Regional Investor",   stocks = 14718},
     {name = "Hafaan Regional Investor", stocks = 3630},
     {name = "Hafaan Regional Investor",     stocks = 3630},
     {name = "Jeseri Regional Investor", stocks = 1870},
     {name = "Jeseri Regional Investor",     stocks = 1870},
     {name = "Hatch Ministry Regional Investor", stocks = 7810},
     {name = "Hatch Ministry Regional Investor", stocks = 7810},
     {name = "New South Jangsong Division", stocks = 11085},
     {name = "New South Jangsong Division",   stocks = 11085},
     {name = "Haifan Bassaridia Division", stocks = 12500},
     {name = "Haifan Bassaridia Division",   stocks = 12500},
}
}


-- Possible reasons for increase or decrease, specifically tied to the General Port
---------------------------------------------------------
-- 3. Reasons for Increase or Decrease
---------------------------------------------------------
local increaseReasons = {
local increaseReasons = {
     "Improved logistics at the General Port attracted new investors.",
     "Improved logistics at the General Port attracted new investors.",
Line 50: Line 71:
     "High attendance at the Bassaridia Trade Symposium enhanced the port's reputation.",
     "High attendance at the Bassaridia Trade Symposium enhanced the port's reputation.",
     "Discovery of new mineral resources near Acheron increased export potential through the port.",
     "Discovery of new mineral resources near Acheron increased export potential through the port.",
     "A surge in ceremonial wine exports from the Blood Vineyards of the Far North bolstered port operations.",
     "A surge in ceremonial wine exports from the Blood Vineyards bolstered port operations.",
     "Efficient cargo handling innovations improved investor sentiment at the General Port.",
     "Efficient cargo handling innovations improved investor sentiment at the General Port.",
     "Seasonal agricultural exports from the Plains of Jogi saw a sharp increase.",
     "Seasonal agricultural exports from the Plains of Jogi saw a sharp increase.",
Line 83: Line 104:
     "High demand for fishing yields outpaced supply, reducing exports through the port.",
     "High demand for fishing yields outpaced supply, reducing exports through the port.",
     "Decline in pearl quality from Anterran sources lowered investor interest.",
     "Decline in pearl quality from Anterran sources lowered investor interest.",
     "Shortage of ceremonial wine from the Blood Vineyards of the Far North hurt exports.",
     "Shortage of ceremonial wine from the Blood Vineyards hurt exports.",
     "Unrest among Maskmaker merchants disrupted key trade agreements.",
     "Unrest among Maskmaker merchants disrupted key trade agreements.",
     "Reduced demand for silk textiles from the Seamstresses of Rouge impacted port activity.",
     "Reduced demand for silk textiles from the Seamstresses of Rouge impacted port activity.",
Line 97: Line 118:
}
}


-- Function to determine tier based on Stocks at End
---------------------------------------------------------
-- 4. Tiers
---------------------------------------------------------
local function determineTier(stocksAtEnd)
local function determineTier(stocksAtEnd)
     if stocksAtEnd > 12500 then
     if stocksAtEnd > 12500 then
Line 108: Line 131:
end
end


-- Function to simulate daily stock activity
---------------------------------------------------------
-- 5. Daily Stock Changes
---------------------------------------------------------
local function simulateDailyActivity(investor)
local function simulateDailyActivity(investor)
     local buyStocks = math.random(0, 500)
     local buyStocks = math.random(0, 500)
Line 117: Line 142:
end
end


-- Function to generate a reason for change
local function getReason(change)
local function getReason(change)
     if change == "Increased" then
     if change == "Increased" then
Line 128: Line 152:
end
end


---------------------------------------------------------
-- 6. Main Function: generateTable
---------------------------------------------------------
function p.generateTable()
function p.generateTable()
     local date, _, _ = getCurrentDate()
    -------------------------------------------------------
    -- Use date-based seeding for daily stable results
    -- i.e. ensures a new random scenario each day
    -------------------------------------------------------
     local dateString, dayOfMonth, month = getCurrentDate()
    -- dailySeed: year * 1000 + dayOfYear:
    local localTime = os.date("*t")
    local dailySeed = localTime.year * 1000 + localTime.yday
    math.randomseed(dailySeed)
 
     local totalMarketValueAtStart = 0
     local totalMarketValueAtStart = 0
     local totalMarketValueAtEnd = 0
     local totalMarketValueAtEnd = 0
     local totalBoughtValue = 0
     local totalBoughtValue = 0
     local totalSoldValue = 0
     local totalSoldValue = 0
     local stockPrice = 30 -- Stock price in Polis
     local stockPrice = 30 -- Stock price in Polis


     local wikitable = "{| class=\"wikitable\"\n! Date (Day/Month/Year [[PSSC]]) !! Investor !! Tier !! Stocks at Start !! Value at Start !! Stocks Bought !! Value of Stocks Bought !! Stocks Sold !! Value of Stocks Sold !! Stocks at End !! Value at End !! Change !! Reason\n"
     local wikitable =  
        '{| class="wikitable"\n' ..
        '! Date (Day/Month/Year [[PSSC]]) !! Investor !! Tier !! Stocks at Start !! Value at Start !! Stocks Bought !! Value of Stocks Bought !! Stocks Sold !! Value of Stocks Sold !! Stocks at End !! Value at End !! Change !! Reason\n'


    -- Process each investor
     for _, investor in ipairs(investors) do
     for _, investor in ipairs(investors) do
        -- Record starting values
         local stocksAtStart = investor.stocks
         local stocksAtStart = investor.stocks
         local valueAtStart = stocksAtStart * stockPrice
         local valueAtStart = stocksAtStart * stockPrice
 
        -- Simulate today's random buy/sell
         local buyStocks, sellStocks = simulateDailyActivity(investor)
         local buyStocks, sellStocks = simulateDailyActivity(investor)
         local valueBought = buyStocks * stockPrice
         local valueBought = buyStocks * stockPrice
         local valueSold = sellStocks * stockPrice
         local valueSold   = sellStocks * stockPrice
 
        -- Record ending values
         local stocksAtEnd = investor.stocks
         local stocksAtEnd = investor.stocks
         local valueAtEnd = stocksAtEnd * stockPrice
         local valueAtEnd = stocksAtEnd * stockPrice
         local tier = determineTier(stocksAtEnd)
         local tier       = determineTier(stocksAtEnd)
 
         local change = "Increased"
         local change = "Increased"
         if stocksAtEnd < stocksAtStart then
         if stocksAtEnd < stocksAtStart then
             change = "Decreased"
             change = "Decreased"
Line 157: Line 201:
         local reason = getReason(change)
         local reason = getReason(change)


        -- Update totals
         totalMarketValueAtStart = totalMarketValueAtStart + valueAtStart
         totalMarketValueAtStart = totalMarketValueAtStart + valueAtStart
         totalMarketValueAtEnd = totalMarketValueAtEnd + valueAtEnd
         totalMarketValueAtEnd   = totalMarketValueAtEnd   + valueAtEnd
         totalBoughtValue = totalBoughtValue + valueBought
         totalBoughtValue       = totalBoughtValue       + valueBought
         totalSoldValue = totalSoldValue + valueSold
         totalSoldValue         = totalSoldValue         + valueSold


         wikitable = wikitable .. string.format("|-\n| %s || %s || %s || %d || %d Polis || %d || %d Polis || %d || %d Polis || %d || %d Polis || %s || %s\n",
        -- Build row
             date, investor.name, tier, stocksAtStart, valueAtStart, buyStocks, valueBought, sellStocks, valueSold, stocksAtEnd, valueAtEnd, change, reason)
         wikitable = wikitable .. string.format(
            "|-\n| %s || %s || %s || %d || %d Polis || %d || %d Polis || %d || %d Polis || %d || %d Polis || %s || %s\n",
             dateString,
            investor.name,
            tier,
            stocksAtStart,
            valueAtStart,
            buyStocks,
            valueBought,
            sellStocks,
            valueSold,
            stocksAtEnd,
            valueAtEnd,
            change,
            reason
        )
     end
     end


     wikitable = wikitable .. string.format("|-\n| colspan=5 | Total Market Value at Start || %d Polis || %d Polis || %d Polis || %d Polis || ||\n",
    -- Totals row
         totalMarketValueAtStart, totalBoughtValue, totalSoldValue, totalMarketValueAtEnd)
     wikitable = wikitable .. string.format(
        "|-\n| colspan=5 | Total Market Value at Start || %d Polis || %d Polis || %d Polis || %d Polis || ||\n",
         totalMarketValueAtStart, totalBoughtValue, totalSoldValue, totalMarketValueAtEnd
    )
     wikitable = wikitable .. "|}"
     wikitable = wikitable .. "|}"
     return wikitable
     return wikitable
end
end


return p
return p

Revision as of 21:22, 26 December 2024

Documentation for this module may be created at Module:BassaridMarketActivity/doc

---------------------------------------------------------
-- Module: BassaridiaDailyInvestorTable
-- Generates a daily table of investor stock activity
-- and associated reasons for increases/decreases.
--
-- Each day:
--  • A unique random seed is derived from the current
--    year and the day of the year (e.g. 2024 * 1000 + 45).
--  • Every cell (stocks, value, reasons) auto-updates
--    but remains stable for that particular day.
---------------------------------------------------------

local p = {}

---------------------------------------------------------
-- 1. Calendar Function
--    Returns date in PSSC terms + numeric dayOfMonth, month
---------------------------------------------------------
local function getCurrentDate()
    local startDate = os.time({year = 1999, month = 8, day = 6})
    local secondsInDay = 86400
    local daysPerYear = 183

    local currentDate = os.time()
    local totalDaysElapsed = math.floor((currentDate - startDate) / secondsInDay)

    local yearFraction = totalDaysElapsed / daysPerYear
    local psscYear = math.floor(yearFraction)
    local dayOfYear = math.floor((yearFraction - psscYear) * daysPerYear) + 1

    local month, dayOfMonth
    if dayOfYear <= 61 then
        month = 1
        dayOfMonth = dayOfYear
    elseif dayOfYear <= 122 then
        month = 2
        dayOfMonth = dayOfYear - 61
    else
        month = 3
        dayOfMonth = dayOfYear - 122
    end

    local dateString = string.format("%d/%d/%d [[PSSC]]", dayOfMonth, month, psscYear)
    return dateString, dayOfMonth, month
end

---------------------------------------------------------
-- 2. Investor Data
---------------------------------------------------------
local investors = {
    {name = "Vaeringheim Regional Investor", stocks = 17424},
    {name = "Alpazkigz Regional Investor",   stocks = 16214},
    {name = "Odiferia Regional Investor",    stocks = 14718},
    {name = "Hafaan Regional Investor",      stocks =  3630},
    {name = "Jeseri Regional Investor",      stocks =  1870},
    {name = "Hatch Ministry Regional Investor", stocks = 7810},
    {name = "New South Jangsong Division",   stocks = 11085},
    {name = "Haifan Bassaridia Division",    stocks = 12500},
}

---------------------------------------------------------
-- 3. Reasons for Increase or Decrease
---------------------------------------------------------
local increaseReasons = {
    "Improved logistics at the General Port attracted new investors.",
    "An influx of goods from Delphica boosted trade volume at the port.",
    "High demand for Noctic-Rabrev exports raised investor confidence in the port's performance.",
    "Completion of a new shipping lane connecting Nexa to the General Port increased activity.",
    "Successful negotiations with Erythros merchants expanded trade opportunities.",
    "The recent Festival of Light in Vaeringheim drove significant port activity.",
    "High attendance at the Bassaridia Trade Symposium enhanced the port's reputation.",
    "Discovery of new mineral resources near Acheron increased export potential through the port.",
    "A surge in ceremonial wine exports from the Blood Vineyards bolstered port operations.",
    "Efficient cargo handling innovations improved investor sentiment at the General Port.",
    "Seasonal agricultural exports from the Plains of Jogi saw a sharp increase.",
    "High sales of pearl and abalone products boosted port activity.",
    "Introduction of luxury goods from Tel-Amin attracted high-end investors.",
    "The expansion of the General Port's capacity in Suncliff enhanced its competitiveness.",
    "Improved relations with Maskmakers Guild merchants stabilized trade routes.",
    "An increase in fishing yields around Lake Morovia led to greater port activity.",
    "Enhanced security measures at the General Port reduced piracy concerns.",
    "Growing cultural appreciation for sacred Horehound exports boosted regional confidence.",
    "Trade agreements with neighboring cities, including Saluria, expanded port usage.",
    "High demand for silk and luxury textiles from Seamstresses of Rouge improved port revenue.",
    "The Moonlit Tide celebration increased ceremonial goods traffic through the port.",
    "Launch of new Garganid fertilizer shipments attracted agricultural investors.",
    "Rising global interest in sacred resin exports enhanced the port's activity.",
    "Successful marketing campaigns highlighted the General Port's strategic importance.",
    "Completion of high-speed rail connections to key cities improved trade efficiency at the port."
}

local decreaseReasons = {
    "Pirate raids in the Strait of Haifa disrupted shipments to the General Port.",
    "Unfavorable weather conditions delayed agricultural exports from the Plains of Jogi.",
    "Labor shortages in the General Port caused delays in cargo handling.",
    "A major fire in Salurian sacred groves reduced resin exports through the port.",
    "Rising costs of Noctic-Rabrev cultivation impacted investor confidence.",
    "Unrest in Jangsong Province disrupted camel meat shipments to the port.",
    "Currency fluctuations in Vaeringheim affected trade stability at the General Port.",
    "Economic sanctions on neighboring cities reduced export activity.",
    "Decline in ceremonial artifact production reduced goods traffic through the port.",
    "Cultural disputes over Horehound cultivation caused delays in exports.",
    "Counterfeit relics discovered in Nexa harmed the port's reputation.",
    "High demand for fishing yields outpaced supply, reducing exports through the port.",
    "Decline in pearl quality from Anterran sources lowered investor interest.",
    "Shortage of ceremonial wine from the Blood Vineyards hurt exports.",
    "Unrest among Maskmaker merchants disrupted key trade agreements.",
    "Reduced demand for silk textiles from the Seamstresses of Rouge impacted port activity.",
    "Collapse of a trade agreement with Tel-Amin reduced port volume.",
    "Seasonal labor shortages in agricultural hubs decreased port shipments.",
    "Disruptions in Suncliff Fisheries slowed aquatic exports through the port.",
    "Discovery of alternative shipping routes bypassed the General Port.",
    "Economic downturn in Lunalis Sancta affected investor interest.",
    "Unresolved piracy concerns in Haifan waters harmed trade confidence.",
    "Failure to secure key trade deals during the Bassaridia Trade Symposium reduced traffic.",
    "Natural disasters near Acheron destroyed key trade routes to the port.",
    "Sabotage of port infrastructure caused significant delays in shipments."
}

---------------------------------------------------------
-- 4. Tiers
---------------------------------------------------------
local function determineTier(stocksAtEnd)
    if stocksAtEnd > 12500 then
        return "Tier I"
    elseif stocksAtEnd >= 5000 and stocksAtEnd <= 12500 then
        return "Tier II"
    else
        return "Tier III"
    end
end

---------------------------------------------------------
-- 5. Daily Stock Changes
---------------------------------------------------------
local function simulateDailyActivity(investor)
    local buyStocks = math.random(0, 500)
    local sellStocks = math.random(0, 500)

    investor.stocks = investor.stocks + buyStocks - sellStocks
    return buyStocks, sellStocks
end

local function getReason(change)
    if change == "Increased" then
        return increaseReasons[math.random(#increaseReasons)]
    elseif change == "Decreased" then
        return decreaseReasons[math.random(#decreaseReasons)]
    else
        return "Market activity remained stable."
    end
end

---------------------------------------------------------
-- 6. Main Function: generateTable
---------------------------------------------------------
function p.generateTable()
    -------------------------------------------------------
    -- Use date-based seeding for daily stable results
    -- i.e. ensures a new random scenario each day
    -------------------------------------------------------
    local dateString, dayOfMonth, month = getCurrentDate()
    -- dailySeed: year * 1000 + dayOfYear:
    local localTime = os.date("*t")
    local dailySeed = localTime.year * 1000 + localTime.yday
    math.randomseed(dailySeed)

    local totalMarketValueAtStart = 0
    local totalMarketValueAtEnd = 0
    local totalBoughtValue = 0
    local totalSoldValue = 0
    local stockPrice = 30  -- Stock price in Polis

    local wikitable = 
        '{| class="wikitable"\n' ..
        '! Date (Day/Month/Year [[PSSC]]) !! Investor !! Tier !! Stocks at Start !! Value at Start !! Stocks Bought !! Value of Stocks Bought !! Stocks Sold !! Value of Stocks Sold !! Stocks at End !! Value at End !! Change !! Reason\n'

    -- Process each investor
    for _, investor in ipairs(investors) do
        -- Record starting values
        local stocksAtStart = investor.stocks
        local valueAtStart  = stocksAtStart * stockPrice

        -- Simulate today's random buy/sell
        local buyStocks, sellStocks = simulateDailyActivity(investor)
        local valueBought = buyStocks * stockPrice
        local valueSold   = sellStocks * stockPrice

        -- Record ending values
        local stocksAtEnd = investor.stocks
        local valueAtEnd  = stocksAtEnd * stockPrice
        local tier        = determineTier(stocksAtEnd)

        local change = "Increased"
        if stocksAtEnd < stocksAtStart then
            change = "Decreased"
        elseif stocksAtEnd == stocksAtStart then
            change = "No Change"
        end

        local reason = getReason(change)

        -- Update totals
        totalMarketValueAtStart = totalMarketValueAtStart + valueAtStart
        totalMarketValueAtEnd   = totalMarketValueAtEnd   + valueAtEnd
        totalBoughtValue        = totalBoughtValue        + valueBought
        totalSoldValue          = totalSoldValue          + valueSold

        -- Build row
        wikitable = wikitable .. string.format(
            "|-\n| %s || %s || %s || %d || %d Polis || %d || %d Polis || %d || %d Polis || %d || %d Polis || %s || %s\n",
            dateString,
            investor.name,
            tier,
            stocksAtStart,
            valueAtStart,
            buyStocks,
            valueBought,
            sellStocks,
            valueSold,
            stocksAtEnd,
            valueAtEnd,
            change,
            reason
        )
    end

    -- Totals row
    wikitable = wikitable .. string.format(
        "|-\n| colspan=5 | Total Market Value at Start || %d Polis || %d Polis || %d Polis || %d Polis || ||\n",
        totalMarketValueAtStart, totalBoughtValue, totalSoldValue, totalMarketValueAtEnd
    )
    wikitable = wikitable .. "|}"

    return wikitable
end

return p