nimFinLib

Program     : nimFinLib

Status      : Development

License     : MIT opensource

Version     : 0.3.0.3

Compiler    : nim 1.0.0 and 1.0.99 devel branch


Description : A basic library for financial data display and calculations
              
              using data from Alpha Vantage API
              
              As mentioned the free API calls allowed are now limited to abt 4/minute , which is
              
              really to low for any reasonable work .
              
              Currency , Stock and Index
              
              Kitco Metal Prices
              
              Dataframe like objects for easy working with current and historical data
              
              EMA,SMA,WMA,RSI,WILLR,BBANDS Indicator   #  may not yet be available for all stocks/markets
              
              Returns calculations
              
              Data display procs
              
              Simple plotting available via gnuplot
              
              Dataframe save/reload complete with display parameters
              
              Dataframe rotation
              
              Portfolio management ( Random portfolio , User portfolio )


Project     :  https://github.com/qqtop/NimFinLib

Tested on   :  Linux

ProjectStart: 2015-06-05

Latest      : 2019-10-01

Todo        : anything not yet done


Programming : qqTop


Installation:
              
              
              nimble install nimcx
              
              nimble install https://github.com/qqtop/nimdataframe.git
              
              nimble install nimFinLib


Notes       :
              
              nimFinlib is being developed utilizing nimcx.nim module and nimdataframe.nim
              
              to improve coloring of data and positioning of output.


Funding     :     Here are the options :
                  
                  You are happy             ==> send BTC to : 194KWgEcRXHGW5YzH1nGqN75WbfzTs92Xk
                  
                  You are not happy         ==> send BTC to : 194KWgEcRXHGW5YzH1nGqN75WbfzTs92Xk
                  
                  You wish to donate        ==> send BTC to : 194KWgEcRXHGW5YzH1nGqN75WbfzTs92Xk
                  
                  You do not wish to donate ==> send BTC to : 194KWgEcRXHGW5YzH1nGqN75WbfzTs92Xk

Indicators

end indicators

Types

Portfolio {...}{.inheritable.} = object
  pfname*: string              ## nx  holds portfolio name  e.g. MyGetRichPortfolio
  pfdata*: seq[Stocks]         ## dx  holds all stocks with historical data
  

Portfolio type

holds one portfolio with all relevant historic stocks data

Account = object
  apf*: seq[Portfolio]         ## pf holds all Portfolio type portfolios for an account
  

Account type

holds all portfolios similar to a master account

portfolios are Portfolio objects

Stocks {...}{.inheritable.} = object of Portfolio
  stock*: string               ## yahoo style stock code ok with alpha vantage api
  date*: seq[string]
  open*: seq[float]
  high*: seq[float]
  low*: seq[float]
  close*: seq[float]
  vol*: seq[float]             ## volume
  adjc*: seq[float]            ## adjusted close price
  ro*: seq[RunningStat]        ## RunningStat for open price
  rh*: seq[RunningStat]        ## RunningStat for high price
  rl*: seq[RunningStat]        ## RunningStat for low price
  rc*: seq[RunningStat]        ## RunningStat for close price
  rv*: seq[RunningStat]        ## RunningStat for volume price
  rca*: seq[RunningStat]       ## RunningStat for adjusted close price
  

Stocks type

holds individual stocks history data and RunningStat for ohlcva columns

even more items may be added like full company name etc in the future

items are stock code, ohlcva, rc and rca .

Vars

avtempdata = "/dev/shm/avdata.csv"

Lets

NIMFINLIBVERSION = "0.3.0.3"

Consts

tail = "tail"
head = "head"
all = "all"

Procs

proc getData22(url: string; timeout: int = 20000): auto {...}{.raises: [IOError, ValueError],
    tags: [TimeEffect, ReadIOEffect, WriteIOEffect, ReadEnvEffect].}
getData
proc avDatafetcher(stckcode: string; mode: string = "compact"; apikey: string): bool {...}{.raises: [
    ValueError, IOError, IOError, ValueError, Exception, OSError, Defect], tags: [
    WriteIOEffect, ReadEnvEffect, TimeEffect, ReadIOEffect, ExecIOEffect, RootEffect,
    WriteDirEffect].}

avDatafetcher

fetches data from alphavantage

default = compact will fetch abt 100 records if available

option = full all available records

Note : first row is real time if markets are open

data will be written into /dev/shm/avdata.csv ..

/dev/shm temporary filesystem location may not be available on every distribution

change accordingly or write to a disc location

this is the best data fetcher for worldwide markets as of 2018-01 others may work too

but currently seem more US focused. it returns av_daily_adjusted_csv

proc avDataFetcherIntraday(stckcode: string; mode: string = "compact"; apikey: string): bool {...}{.raises: [
    ValueError, IOError, IOError, ValueError, Exception, OSError, Defect], tags: [
    WriteIOEffect, ReadEnvEffect, TimeEffect, ReadIOEffect, ExecIOEffect, RootEffect,
    WriteDirEffect].}

avDataFetcherIntraday

fetches data from alphavantage

default = compact abt 100 records if available

option = full all available records

Note : first row is real time if markets are open

data will be written into /dev/shm/avdata.csv ..

/dev/shm temporary filesystem location may not be available on every distribution

change accordingly or write to a disc location

works occassionally with non US stocks but mostly not ...

proc avDataFetcherGlobal(stckcode: string; mode: string = "compact"; apikey: string): bool {...}{.raises: [
    IOError, ValueError, IOError, ValueError, Exception, OSError, Defect], tags: [
    WriteIOEffect, ReadEnvEffect, WriteDirEffect, ReadIOEffect, TimeEffect,
    ExecIOEffect, RootEffect].}

avDataFetcherGlobal

fetches data from alphavantage

default = compact

data will be written into /dev/shm/avdata.csv ..

change accordingly or write to a disc location

works occassionally with non US stocks but mostly not ...

proc avDataFetcherGlobal(stckcodes: seq[string]; mode: string = "compact";
                        apikey: string): bool {...}{.
    raises: [OSError, IOError, ValueError, IOError, ValueError], tags: [WriteDirEffect,
    WriteIOEffect, ReadEnvEffect, ReadIOEffect, TimeEffect].}

avDataFetcherGlobal

fetches data from alphavantage

default = compact

here we provide a seq of stockcodes to fetch

data will be written into /dev/shm/avdata.csv ..

change accordingly or write to a disc location

works occassionally with non US stocks but mostly not ...

proc showRawData() {...}{.raises: [IOError, ValueError, OSError, Exception],
                   tags: [ReadDirEffect, WriteIOEffect, ReadEnvEffect].}

showRawData

displays raw data currently in avtempdata

proc showOriginalStockDf(stckcode: string; xpos: int = 3; rows: int = 3;
                        header: bool = false; apikey: string = "demo"): nimdf {...}{.
    discardable, raises: [ValueError, IOError, Exception, OSError, Defect, IOError,
                        ValueError, Exception, OSError, HttpRequestError, SslError,
                        OverflowError, TimeoutError, ProtocolError, KeyError,
                        CsvError, IOError, ValueError], tags: [WriteIOEffect,
    ReadEnvEffect, TimeEffect, ReadIOEffect, ExecIOEffect, RootEffect, WriteDirEffect].}

showOriginalStockData WIP

using TIME_SERIES_INTRADAY 1 min DATA # this will be selectable in the future in respect of time_series and interval

first data row maybe realtime if markets online , we always fetch fresh data

proc showStocksDf(stckcode: string; rows: int = 3; xpos: int = 3; header: bool = false;
                 mode: string = "compact"; infodf: bool = true; apikey: string = "demo"): nimdf {...}{.
    discardable, raises: [ValueError, IOError, Exception, OSError, Defect, IOError,
                        ValueError, Exception, OSError, HttpRequestError, SslError,
                        OverflowError, TimeoutError, ProtocolError, KeyError,
                        CsvError], tags: [TimeEffect, WriteIOEffect, ReadEnvEffect,
                                        ReadIOEffect, ExecIOEffect, RootEffect,
                                        WriteDirEffect].}

showStocksDf

a display routine with some more information

data is freshly downloaded

proc showLocalStocksDf(ndf9: nimdf; xpos: int = 3): nimdf {...}{.discardable,
    raises: [ValueError, IOError, Exception, OSError, Defect], tags: [WriteIOEffect,
    ReadEnvEffect, ReadIOEffect, TimeEffect, ExecIOEffect, RootEffect, WriteDirEffect].}

showLocalStocksDf

used to display a df which already exists or has been loaded via dfLoad

with all parameters pre specified

proc getavSMA(stckcode: string; interval: string = "15min"; timeperiod: string = "10";
             seriestype: string = "close"; apikey: string; xpos: int = 3;
             savequiet: bool = true; dfinfo: bool = false) {...}{.raises: [ValueError, IOError,
    IOError, ValueError, Exception, OSError, Defect, JsonParsingError, IOError,
    ValueError, KeyError], tags: [TimeEffect, ReadIOEffect, WriteIOEffect,
                               ReadEnvEffect, ExecIOEffect, RootEffect,
                               WriteDirEffect].}

getavSMA

fetches data from alphavantage

Note : first row is real time if markets are open

interval : 1min, 5min, 15min, 30min, 60min, daily, weekly, monthly

timeperiod : time_period=60, time_period=200 etc.

seriestype : close, open, high, low

proc getavWMA(stckcode: string; interval: string = "15min"; timeperiod: string = "10";
             seriestype: string = "close"; apikey: string; xpos: int = 3;
             savequiet: bool = true; dfinfo: bool = false) {...}{.raises: [ValueError, IOError,
    IOError, ValueError, Exception, OSError, Defect, JsonParsingError, IOError,
    ValueError, KeyError], tags: [TimeEffect, ReadIOEffect, WriteIOEffect,
                               ReadEnvEffect, ExecIOEffect, RootEffect,
                               WriteDirEffect].}

getavWMA

fetches data from alphavantage

Note : first row is real time if markets are open

interval : 1min, 5min, 15min, 30min, 60min, daily, weekly, monthly

timeperiod : time_period=60, time_period=200 etc.

seriestype : close, open, high, low

proc getavEMA(stckcode: string; interval: string = "15min"; timeperiod: string = "10";
             seriestype: string = "close"; apikey: string; xpos: int = 3;
             savequiet: bool = true; dfinfo: bool = false) {...}{.raises: [ValueError, IOError,
    IOError, ValueError, Exception, OSError, Defect, JsonParsingError, IOError,
    ValueError, KeyError], tags: [TimeEffect, ReadIOEffect, WriteIOEffect,
                               ReadEnvEffect, ExecIOEffect, RootEffect,
                               WriteDirEffect].}

getavEMA

fetches data from alphavantage

Note : first row is real time if markets are open

interval : 1min, 5min, 15min, 30min, 60min, daily, weekly, monthly

timeperiod : time_period=60, time_period=200 etc.

seriestype : close, open, high, low

proc getavRSI(stckcode: string; interval: string = "15min"; timeperiod: string = "10";
             seriestype: string = "close"; apikey: string; xpos: int = 3;
             savequiet: bool = true; dfinfo: bool = false) {...}{.raises: [ValueError, IOError,
    IOError, ValueError, Exception, OSError, Defect, JsonParsingError, IOError,
    ValueError, KeyError], tags: [TimeEffect, ReadIOEffect, WriteIOEffect,
                               ReadEnvEffect, ExecIOEffect, RootEffect,
                               WriteDirEffect].}
getavRSI fetches data from alphavantage Note : first row is real time if markets are open interval : 1min, 5min, 15min, 30min, 60min, daily, weekly, monthly timeperiod : time_period=60, time_period=200 etc. seriestype : close, open, high, low
proc getavWILLR(stckcode: string; interval: string = "15min";
               timeperiod: string = "10"; seriestype: string = "close"; apikey: string;
               xpos: int = 3; savequiet: bool = true; dfinfo: bool = false) {...}{.raises: [
    ValueError, IOError, IOError, ValueError, Exception, OSError, Defect,
    JsonParsingError, IOError, ValueError, KeyError], tags: [TimeEffect, ReadIOEffect,
    WriteIOEffect, ReadEnvEffect, ExecIOEffect, RootEffect, WriteDirEffect].}
getavWILLR fetches data from alphavantage Note : first row is real time if markets are open interval : 1min, 5min, 15min, 30min, 60min, daily, weekly, monthly timeperiod : time_period=60, time_period=200 etc. seriestype : close, open, high, low getavWILLR("MSFT","15min","10","close",apikey = apikey, 3, true, false)
proc getavBBANDS(stckcode: string; interval: string = "15min";
                timeperiod: string = "10"; seriestype: string = "close"; apikey: string;
                xpos: int = 3; savequiet: bool = true; dfinfo: bool = false) {...}{.raises: [
    ValueError, IOError, IOError, ValueError, Exception, OSError, Defect,
    JsonParsingError, IOError, ValueError, KeyError], tags: [TimeEffect, ReadIOEffect,
    WriteIOEffect, ReadEnvEffect, ExecIOEffect, RootEffect, WriteDirEffect].}
getavBBANDS fetches data from alphavantage Note : first row is real time if markets are open interval : 1min, 5min, 15min, 30min, 60min, daily, weekly, monthly timeperiod : time_period=60, time_period=200 etc. seriestype : close, open, high, low default params implemented here see ---> https://www.alphavantage.co/documentation/
proc showKitcoMetal(xpos: int = 1) {...}{.raises: [IOError, ValueError], tags: [ReadIOEffect,
    WriteIOEffect, TimeEffect, ReadEnvEffect].}

showKitcoMetal

get and display kitco metal prices

proc williams_percent_r(close_data: seq[float]): seq[float] {...}{.raises: [], tags: [].}
proc dailyReturns(self: seq[string]): nimss {...}{.raises: [ValueError], tags: [].}

dailyReturns

daily returns calculation gives same results as dailyReturns in R / quantmod

proc presentValue[T](FV: T; r: T; m: int; t: int): float

presentValue

Present Value Calculation for a Lump Sum Investment

Future Value (FV)
is the future value sum of an investment that you want to find a present value for
Number of Periods (t)
commonly this will be number of years but periods can be any time unit. Use int or floats for partial periods such as months for example, 7.5 years is 7 yr 6 mo.
Interest Rate (R)
is the annual nominal interest rate or "stated rate" in percent. r = R/100, the interest rate in integer or floats
Compounding (m)
is the number of times compounding occurs per period. If a period is a year then annually=1, quarterly=4, monthly=12, daily = 365, etc.
Rate (i)
i = (r/m); interest rate per compounding period.
Total Number of Periods (n)
n = mt; is the total number of compounding periods for the life of the investment.
Present Value (PV)
the calculated present value of your future value amount

From http://www.CalculatorSoup.com - Online Calculator Resource.

var FV : float = 10000
var PV : float = 0.0
var r  : float = 0.0625
var m  : int   = 2
var t  : int   = 12

PV = presentValue(FV,r,m,t)
echo PV
proc presentValue(FV: float; r: float; m: float; t: float): float {...}{.raises: [], tags: [].}

presentValue

Present Value Calculation for a Lump Sum Investment

PV = presentValue(FV,0.0925,2.0,12.0)
echo PV
proc presentValueFV(FV: float; i: float; n: int): float {...}{.raises: [], tags: [].}

presentValueFV

the present value of a future sum at a periodic interest rate i where n is the number of periods in the future.

PV = presentValueFV(FV,0.0625,10)
echo PV
proc presentValueFV(FV: float; i: float; n: float): float {...}{.raises: [], tags: [].}
PV = presentValueFV(FV,0.0625,20.5)
echo PV