using ZipFile
using Dates
using Random
using CSV

"""
Generator for data in the same format as
https://www.truefx.com/truefx-historical-downloads/

Generates one gzipped CSV per month, with a line format like

AUD/USD,20160104 00:00:00.108,0.72845,0.72849
"""
function generate_year(directory, pair, t_start, start_bid, movement)
    t = DateTime(t_start)
    for month = 1:12
        month_end = t_start + Month(month)
        month_start = t_start + Month(month-1)
        timestamps = DateTime[]
        while t < month_end
            if dayofweek(t) in (6,7)
                # Not traded on weekends
                t += Day(2)
            else
                # Weekday
                push!(timestamps, t)
                # The real data is 100x heavier than this -
                # it has one sample per ~0.5 seconds
                t += Millisecond(rand(20000:80000))
            end
        end
        N = length(timestamps)
        # No-doubt-very-unrealistic movement generated via Brownian motion
        m = (0.05/(sqrt(N) * movement)) .* cumsum(randn(N))
        bid = start_bid .+ m
        ask = bid .+ (start_bid*1e-5)*rand(length(timestamps))
        bid = round.(bid, digits=5)
        ask = round.(ask, digits=5)
        start_bid = bid[end]
        io = IOBuffer()
        CSV.write(io, (pair=fill(pair,N),
                       timestamps=timestamps,
                       bid=bid,
                       ask=ask),
                  dateformat=dateformat"yyyymmdd HH:MM:SS.s",
                  header=false)
        filename_prefix = "$(replace(pair, '/'=>""))-$(year(month_start))-$(string(Dates.month(month_start),pad=2))"
        zwriter = ZipFile.Writer(joinpath(directory, "$filename_prefix.zip"))
        write(ZipFile.addfile(zwriter, "$filename_prefix.csv"), take!(io))
        close(zwriter)
    end
end

# A couple of fake currency pairs.
# Don't want people mistaking this for real data!
pairs = [("EUU/UDD", 1.30, 0.2),
         ("UDD/JPP", 89.0, 10)]
directory = "currency_data"
mkpath(directory)
Random.seed!(1)
for (pair_name,start_bid) in pairs
    generate_year(directory, pair_name, Date(2020), start_bid, 1)
end


# Generate Data.toml for DataSets.jl
write("Data.toml", """
    data_config_version=0

    #--------------------------------------------------
    [[datasets]]
    description="Synthetic currency data, in TrueFX format"
    name="currency_data"
    uuid="1a679260-0462-455f-9a91-4d9759eeda2b"

        [datasets.storage]
        driver="FileSystem"
        type="BlobTree"
        path="@__DIR__/$directory"
    """
)
