Fixed tons of bugs and made the return data cleaner

This commit is contained in:
Ryan Ward 2018-08-26 18:07:24 -04:00
parent f57f5db449
commit a0848a649b
7 changed files with 2191 additions and 26 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
test.lua

537
DCL.dat Normal file
View File

@ -0,0 +1,537 @@
currency code,currency name
1ST,FirstBlood
2GIVE,GiveCoin
808,808Coin
ABT,ArcBlock
ABY,ArtByte
AC,AsiaCoin
ACT,Achain
ADA,Cardano
ADT,adToken
ADX,AdEx
AE,Aeternity
AEON,Aeon
AGI,SingularityNET
AGRS,IDNI-Agoras
AI,POLY-AI
AID,AidCoin
AION,Aion
AIR,AirToken
AKY,Akuya-Coin
ALIS,ALIS
AMBER,AmberCoin
AMP,Synereo
ANC,Anoncoin
ANT,Aragon
APPC,AppCoins
APX,APX-Ventures
ARDR,Ardor
ARK,Ark
ARN,Aeron
AST,AirSwap
ATB,ATBCoin
ATM,ATMChain
ATS,Authorship
AUR,Auroracoin
AVT,Aventus
B3,B3Coin
BAT,Basic-Attention-Token
BAY,BitBay
BBR,Boolberry
BCAP,BCAP
BCC,BitConnect
BCD,Bitcoin-Diamond
BCH,Bitcoin-Cash
BCN,Bytecoin
BCPT,BlockMason-Credit-Protocol-Token
BCX,BitcoinX
BCY,BitCrystals
BDL,Bitdeal
BEE,Bee-Token
BELA,BelaCoin
BET,DAO-Casino
BFT,BF-Token
BIS,Bismuth
BITB,BitBean
BITBTC,BitBTC
BITCNY,BitCNY
BITEUR,BitEUR
BITGOLD,BitGOLD
BITSILVER,BitSILVER
BITUSD,BitUSD
BIX,Bibox-Token
BLITZ,Blitzcash
BLK,Blackcoin
BLN,Bolenum
BLOCK,Blocknet
BLZ,Bluzelle
BMC,Blackmoon-Crypto
BNB,Binance-Coin
BNT,Bancor-Network-Token
BNTY,Bounty0x
BOST,BoostCoin
BOT,Bodhi
BQ,bitqy
BRD,Bread
BRK,Breakout-Coin
BRX,Breakout-Stake
BTA,Bata
BTC,Bitcoin
BTCD,BitcoinDark
BTCP,Bitcoin-Private
BTG,Bitcoin-Gold
BTM,Bitmark
BTS,BitShares
BTSR,BTSR
BTX,Bitcore
BURST,Burstcoin
BUZZ,BuzzCoin
BYC,Bytecent
BYTOM,Bytom
C20,Crypto20
CANN,CannabisCoin
CAT,BlockCAT
CCRB,CryptoCarbon
CDT,Blox
CFI,Cofound-it
CHAT,ChatCoin
CHIPS,Chips
CLAM,Clams
CLOAK,CloakCoin
CMP,Compcoin
CMT,CyberMiles
CND,Cindicator
CNX,Cryptonex
COFI,CoinFi
COSS,COSS
COVAL,Circuits-Of-Value
CRBIT,CreditBIT
CREA,CreativeCoin
CREDO,Credo
CRW,Crown
CSNO,BitDice
CTR,Centra
CTXC,Cortex
CURE,CureCoin
CVC,Civic
DAI,Dai
DAR,Darcrus
DASH,Dash
DATA,DATAcoin
DAY,Chronologic
DBC,DeepBrain-Chain
DBIX,DubaiCoin
DCN,Dentacoin
DCR,Decred
DCT,DECENT
DDF,Digital-Developers-Fund
DENT,Dent
DFS,DFSCoin
DGB,DigiByte
DGC,Digitalcoin
DGD,DigixDAO
DICE,Etheroll
DLT,Agrello-Delta
DMD,Diamond
DMT,DMarket
DNT,district0x
DOGE,DogeCoin
DOPE,DopeCoin
DRGN,Dragonchain
DTA,Data
DTB,Databits
DYN,Dynamic
EAC,EarthCoin
EBST,eBoost
EBTC,eBTC
ECC,ECC
ECN,E-coin
EDG,Edgeless
EDO,Eidoo
EFL,Electronic-Gulden
EGC,EverGreenCoin
EKT,EDUCare
ELA,Elastos
ELEC,Electrify.Asia
ELF,aelf
ELIX,Elixir
EMB,Embercoin
EMC,Emercoin
EMC2,Einsteinium
ENG,Enigma
ENJ,Enjin-Coin
ENRG,EnergyCoin
EOS,EOS
EOT,EOT-Token
EQT,EquiTrader
ERC,EuropeCoin
ETC,Ethereum-Classic
ETH,Ethereum
ETHD,Ethereum-Dark
ETHOS,Ethos
ETN,Electroneum
ETP,Metaverse-Entropy
ETT,EncryptoTel
EVE,Devery
EVX,Everex
EXCL,ExclusiveCoin
EXP,Expanse
FCT,Factom
FLDC,FoldingCoin
FLO,FlorinCoin
FLT,FlutterCoin
FRST,FirstCoin
FTC,Feathercoin
FUEL,Etherparty
FUN,FunFair
GAM,Gambit
GAME,GameCredits
GAS,Gas
GBG,Golos Gold
GBX,GoByte
GBYTE,Byteball
GCR,GCRCoin
GEO,GeoCoin
GLD,GoldCoin
GNO,Gnosis-Token
GNT,Golem-Tokens
GOLOS,Golos
GRC,Gridcoin
GRS,Groestlcoin
GRWI,Growers-International
GTC,Game
GTO,Gifto
GUP,Guppy
GVT,Genesis-Vision
GXS,GXShares
HBN,HoboNickels
HEAT,HEAT
HMQ,Humaniq
HPB,High-Performance-Blockchain
HSR,Hshare
HUSH,Hush
HVN,Hive
HXX,HexxCoin
ICN,ICONOMI
ICX,ICON
IFC,Infinitecoin
IFT,investFeed
IGNIS,Ignis
INCNT,Incent
IND,Indorse-Token
INF,InfChain
INK,Ink
INS,INS-Ecosystem
INSTAR,Insights-Network
INT,Internet-Node-Token
INXT,Internxt
IOC,IOCoin
ION,ION
IOP,Internet-of-People
IOST,IOStoken
IOTA,IOTA
IOTX,IoTeX
IQT,Iquant-Chain
ITC,IoT-Chain
IXC,iXcoin
IXT,InsureX
J8T,JET8
JNT,Jibrel-Network
KCS,KuCoin
KICK,KickCoin
KIN,KIN
KMD,Komodo
KNC,Kyber-Network
KORE,KoreCoin
LBC,LBRY-Credits
LCC,Litecoin-Cash
LEND,EthLend
LEV,Leverj
LGD,Legends-Room
LINDA,Linda
LINK,ChainLink
LKK,Lykke
LMC,LoMoCoin
LOCI,LOCIcoin
LOOM,Loom-Token
LRC,Loopring
LSK,Lisk
LTC,Litecoin
LUN,Lunyr
MAID,MaidSafeCoin
MANA,Decentraland
MAX,Maxcoin
MBRS,Embers
MCAP,MCAP
MCO,Monaco
MDA,Moeda-Loyalty-Points
MEC,Megacoin
MED,MediBlock
MEME,Memetic
MER,Mercury
MGC,MergeCoin
MGO,MobileGo
MINEX,Minex
MINT,Mintcoin
MITH,Mithril
MKR,Maker
MLN,Melon
MNE,Minereum
MNX,MinexCoin
MOD,Modum
MONA,MonaCoin
MRT,Miners-Reward-Token
MSP,Mothership
MTH,Monetha
MTN,MedToken
MUE,MonetaryUnit
MUSIC,Musicoin
MYB,MyBit-Token
MYST,Mysterium
MZC,Mazacoin
NAMO,Namocoin
NANO,Nano
NAS,Nebulas-Token
NAV,Nav-Coin
NBT,NuBits
NCASH,Nucleus-Vision
NDC,NeverDie-Coin
NEBL,Neblio
NEO,NEO
NEOS,NeosCoin
NET,Nimiq
NLC2,NoLimitCoin
NLG,Gulden
NMC,Namecoin
NMR,Numeraire
NOBL,NobleCoin
NOTE,DNotes
NPXS,Pundi-X-Token
NSR,NuShares
NTO,Fujinto
NULS,Nuls
NVC,Novacoin
NXC,Nexium
NXS,Nexus
NXT,Nxt
OAX,openANX
OBITS,Obits
OCL,Oceanlab
OCN,Odyssey
ODEM,ODEM
ODN,Obsidian
OF,OFCOIN
OK,OKCash
OMG,OmiseGo
OMNI,Omni
ONION,DeepOnion
ONT,Ontology
OPT,Opus
OST,Simple-Token
PART,Particl
PASC,PascalCoin
PAY,TenX
PBL,Pebbles
PBT,Primalbase-Token
PFR,Payfair
PING,CryptoPing
PINK,Pinkcoin
PIVX,PIVX
PIX,Lampix
PLBT,Polybius
PLR,Pillar
PLU,Pluton
POA,POA-Network
POE,Poet
POLY,Polymath
POSW,PoSW-Coin
POT,PotCoin
POWR,Power-Ledger
PPC,Peercoin
PPT,Populous
PPY,Peerplays
PRG,Paragon-Coin
PRL,Oyster-Pearl
PRO,Propy
PST,Primas
PTC,Pesetacoin
PTOY,Patientory
PURA,Pura
QASH,QASH
QAU,Quantum
QLC,Qlink
QRK,Quark
QRL,Quantum-Resistant-Ledger
QSP,Quantstamp
QTL,Quatloo
QTUM,Qtum
QWARK,Qwark
R,Revain
RADS,Radium
RAIN,Condensate
RBIES,Rubies
RBX,Ripto-Bux
RBY,RubyCoin
RCN,Ripio-Credit-Network
RDD,ReddCoin
RDN,Raiden-Network-Token
REC,Regalcoin
RED,Redcoin
REP,Augur
REQ,Request-Network
RHOC,RChain
RIC,Riecoin
RISE,Rise
RLC,RLC-Token
RLT,RouletteToken
RPX,Red-Pulse
RRT,Recovery-Right-Tokens
RUFF,Ruff
RUP,Rupee
RVT,Rivetz
SAFEX,SafeExchangeCoin
SALT,Salt
SAN,Santiment-Network-Token
SBD,Steem-Dollars
SBTC,Super-Bitcoin
SC,Siacoin
SEELE,Seele
SEQ,Sequence
SHIFT,SHIFT
SIB,SIBCoin
SIGMA,SIGMAcoin
SIGT,Signatum
SJCX,Storjcoin-X
SKIN,SkinCoin
SKY,Skycoin
SLR,SolarCoin
SLS,SaluS
SMART,SmartCash
SMT,SmartMesh
SNC,SunContract
SNGLS,SingularDTV
SNM,SONM
SNRG,Synergy
SNT,Status-Network-Token
SOC,All-Sports
SOUL,Phantasma
SPANK,SpankChain
SPC,SpaceChain
SPHR,Sphere
SPR,SpreadCoin
SRN,Sirin-Labs-Token
START,Startcoin
STEEM,Steem
STK,STK-Token
STORJ,Storj
STORM,Storm
STQ,Storiqa
STRAT,Stratis
STX,Stox
SUB,Substratum
SWFTC,SwftCoin
SWIFT,Bitswift
SWT,Swarm-City
SYNX,Syndicate
SYS,SysCoin
TAAS,Taas
TAU,Lamden
TCC,The-ChampCoin
TFL,True-Flip
THC,HempCoin
THETA,Theta-Token
TIME,Time
TIX,Blocktix
TKN,TokenCard
TKR,Trackr
TKS,Tokes
TNB,Time-New-Bank
TNT,Tierion
TOA,ToaCoin
TRAC,OriginTrail
TRC,Terracoin
TRCT,Tracto
TRIG,Triggers
TRST,Trustcoin
TRUE,TrueChain
TRUST,TrustPlus
TRX,Tronix
TUSD,TrueUSD
TX,TransferCoin
UBQ,Ubiq
UKG,UnikoinGold
ULA,Ulatech
UNB,UnbreakableCoin
UNITY,SuperNET
UNO,Unobtanium
UNY,Unity-Ingot
UP,UpToken
URO,Uro
USDT,Tether
UTK,UTrust
VEE,BLOCKv
VEN,VeChain
VERI,Veritaseum
VIA,Viacoin
VIB,Viberate
VIBE,Vibe
VIVO,VIVO
VOISE,Voise
VOX,Voxels
VPN,VPNCoin
VRC,Vericoin
VRM,Verium
VRS,Veros
VSL,vSlice
VTC,Vertcoin
VTR,vTorrent
WABI,WaBi
WAN,Wanchain
WAVES,Waves
WAX,Wax-Token
WCT,Waves-Community
WDC,WorldCoin
WGO,WavesGo
WGR,Wagerr
WINGS,Wings
WPR,WePower
WTC,Walton
WTT,Giga-Watt-Token
XAS,Asch
XAUR,Xaurum
XBC,Bitcoin-Plus
XBY,XtraBYtes
XCN,Cryptonite
XCP,Counterparty
XDN,DigitalNote
XEL,Elastic
XEM,NEM
XID,Sphere-Identity
XLM,Stellar
XMG,Magi
XMR,Monero
XMT,Metal
XMY,Myriadcoin
XPM,Primecoin
XRL,Rialto
XRP,Ripple
XSPEC,Spectrecoin
XST,Stealthcoin
XTZ,Tezos
XUC,Exchange-Union
XVC,Vcash
XVG,Verge
XWC,WhiteCoin
XZC,ZCoin
XZR,ZrCoin
YEE,Yee
YOYOW,YOYOW
ZCC,ZcCoin
ZCL,Zclassic
ZCO,Zebi
ZEC,Zcash
ZEN,ZenCash
ZET,Zetacoin
ZIL,Zilliqa
ZLA,Zilla
ZRX,0x

157
PCL.dat Normal file
View File

@ -0,0 +1,157 @@
currency code,currency name
AED,United Arab Emirates Dirham
AFN,Afghan Afghani
ALL,Albanian Lek
AMD,Armenian Dram
ANG,Netherlands Antillean Guilder
AOA,Angolan Kwanza
ARS,Argentine Peso
AUD,Australian Dollar
AWG,Aruban Florin
AZN,Azerbaijani Manat
BAM,Bosnia-Herzegovina Convertible Mark
BBD,Barbadian Dollar
BDT,Bangladeshi Taka
BGN,Bulgarian Lev
BHD,Bahraini Dinar
BIF,Burundian Franc
BMD,Bermudan Dollar
BND,Brunei Dollar
BOB,Bolivian Boliviano
BRL,Brazilian Real
BSD,Bahamian Dollar
BTN,Bhutanese Ngultrum
BWP,Botswanan Pula
BZD,Belize Dollar
CAD,Canadian Dollar
CDF,Congolese Franc
CHF,Swiss Franc
CLF,Chilean Unit of Account UF
CLP,Chilean Peso
CNH,Chinese Yuan Offshore
CNY,Chinese Yuan
COP,Colombian Peso
CUP,Cuban Peso
CVE,Cape Verdean Escudo
CZK,Czech Republic Koruna
DJF,Djiboutian Franc
DKK,Danish Krone
DOP,Dominican Peso
DZD,Algerian Dinar
EGP,Egyptian Pound
ERN,Eritrean Nakfa
ETB,Ethiopian Birr
EUR,Euro
FJD,Fijian Dollar
FKP,Falkland Islands Pound
GBP,British Pound Sterling
GEL,Georgian Lari
GHS,Ghanaian Cedi
GIP,Gibraltar Pound
GMD,Gambian Dalasi
GNF,Guinean Franc
GTQ,Guatemalan Quetzal
GYD,Guyanaese Dollar
HKD,Hong Kong Dollar
HNL,Honduran Lempira
HRK,Croatian Kuna
HTG,Haitian Gourde
HUF,Hungarian Forint
IDR,Indonesian Rupiah
ILS,Israeli New Sheqel
INR,Indian Rupee
IQD,Iraqi Dinar
IRR,Iranian Rial
JEP,Jersey Pound
JMD,Jamaican Dollar
JOD,Jordanian Dinar
JPY,Japanese Yen
KES,Kenyan Shilling
KGS,Kyrgystani Som
KHR,Cambodian Riel
KMF,Comorian Franc
KPW,North Korean Won
KRW,South Korean Won
KWD,Kuwaiti Dinar
KYD,Cayman Islands Dollar
KZT,Kazakhstani Tenge
LAK,Laotian Kip
LBP,Lebanese Pound
LKR,Sri Lankan Rupee
LRD,Liberian Dollar
LSL,Lesotho Loti
LYD,Libyan Dinar
MAD,Moroccan Dirham
MDL,Moldovan Leu
MGA,Malagasy Ariary
MKD,Macedonian Denar
MMK,Myanma Kyat
MNT,Mongolian Tugrik
MOP,Macanese Pataca
MRO,Mauritanian Ouguiya (pre-2018)
MRU,Mauritanian Ouguiya
MUR,Mauritian Rupee
MVR,Maldivian Rufiyaa
MWK,Malawian Kwacha
MXN,Mexican Peso
MYR,Malaysian Ringgit
MZN,Mozambican Metical
NAD,Namibian Dollar
NGN,Nigerian Naira
NOK,Norwegian Krone
NPR,Nepalese Rupee
NZD,New Zealand Dollar
OMR,Omani Rial
PAB,Panamanian Balboa
PEN,Peruvian Nuevo Sol
PGK,Papua New Guinean Kina
PHP,Philippine Peso
PKR,Pakistani Rupee
PLN,Polish Zloty
PYG,Paraguayan Guarani
QAR,Qatari Rial
RON,Romanian Leu
RSD,Serbian Dinar
RUB,Russian Ruble
RUR,Old Russian Ruble
RWF,Rwandan Franc
SAR,Saudi Riyal
SBDf,Solomon Islands Dollar
SCR,Seychellois Rupee
SDG,Sudanese Pound
SEK,Swedish Krona
SGD,Singapore Dollar
SHP,Saint Helena Pound
SLL,Sierra Leonean Leone
SOS,Somali Shilling
SRD,Surinamese Dollar
SYP,Syrian Pound
SZL,Swazi Lilangeni
THB,Thai Baht
TJS,Tajikistani Somoni
TMT,Turkmenistani Manat
TND,Tunisian Dinar
TOP,Tongan Pa'anga
TRY,Turkish Lira
TTD,Trinidad and Tobago Dollar
TWD,New Taiwan Dollar
TZS,Tanzanian Shilling
UAH,Ukrainian Hryvnia
UGX,Ugandan Shilling
USD,United States Dollar
UYU,Uruguayan Peso
UZS,Uzbekistan Som
VND,Vietnamese Dong
VUV,Vanuatu Vatu
WST,Samoan Tala
XAF,CFA Franc BEAC
XAG,Silver Ounce
XAU,Gold Ounce
XCD,East Caribbean Dollar
XDR,Special Drawing Rights
XOF,CFA Franc BCEAO
XPF,CFP Franc
YER,Yemeni Rial
ZAR,South African Rand
ZMW,Zambian Kwacha
ZWL,Zimbabwean Dollar

View File

@ -1,8 +1,20 @@
local https = require("ssl.https")
local bin = require("bin")
local alpha = {}
alpha.APIKey = ""
function string:split( inSplitPattern, outResults)
local _,https = pcall(require,"ssl.https")
local _,luajitrequest = pcall(require,"luajit-request")
local request
if https then
function request(url)
return https.request(url)
end
end
if luajitrequest and not https then
function request(url)
return luajitrequest.send(url).body
end
end
function string:split(inSplitPattern, outResults)
if not outResults then
outResults = {}
end
@ -24,7 +36,7 @@ function alpha.getPhysicalCurrencyList(force)
if bin.fileExists("PCL.dat") and not force then
dat = bin.load("PCL.dat").data
else
dat = https.request("https://www.alphavantage.co/physical_currency_list/")
dat = request("https://www.alphavantage.co/physical_currency_list/")
bin.new(dat):tofile("PCL.dat")
end
if alpha.pcl then return alpha.pcl end
@ -43,7 +55,7 @@ function alpha.getDigitalCurrencyList(force)
if bin.fileExists("DCL.dat") and not force then
dat = bin.load("DCL.dat").data
else
dat = https.request("https://www.alphavantage.co/digital_currency_list/")
dat = request("https://www.alphavantage.co/digital_currency_list/")
bin.new(dat):tofile("DCL.dat")
end
if alpha.dcl then return alpha.dcl end
@ -58,20 +70,21 @@ function alpha.getDigitalCurrencyList(force)
return c
end
function alpha.dataToTable(data)
local c = {}
local order = {}
local c = {
MetaData = {},
History = {}
}
local lines = data:lines(str)
local tab = {}
local tag = lines[1]:split(",")
for i = 2,#lines-1 do
tab = lines[i]:split(",")
c[tab[1]]={}
local t={}
c.History[#c.History+1]=t
for e = 1,#tag do
order[#order+1]=tab[1]
c[tab[1]][tag[e]]=tab[e]
t[tag[e]]=tab[e]
end
end
c.order = order
return c
end
local function simpleparse(command,symbols,outputsize,interval)
@ -89,11 +102,15 @@ local function simpleparse(command,symbols,outputsize,interval)
end
for i=1,#symbols do
cmd = "https://www.alphavantage.co/query?function="..command.."&symbol="..symbols[i].."&datatype=csv&apikey="..alpha.APIKey..outputsize..str
dat = https.request(cmd)
dat = request(cmd)
if dat:find("Invalid API call") then
return nil, "Invalid API call"
else
data[symbols[i]]=alpha.dataToTable(dat)
data[i]=alpha.dataToTable(dat)
data[i].MetaData = {
Symbol = symbols[i],
MostRecentData = data[i].History[1]
}
end
end
return data
@ -122,6 +139,30 @@ end
function alpha.timeSeriesMonthlyAdjusted(symbols,outputsize)
return simpleparse("TIME_SERIES_MONTHLY_ADJUSTED",symbols,outputsize)
end
-- api.GLOBAL_QUOTE
function alpha.globalQuote(symbols)
local cmd
local data = {}
if type(symbols)=="string" then
symbols = {symbols}
end
local str = ""
for i=1,#symbols do
cmd = "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol="..symbols[i].."&datatype=csv&apikey="..alpha.APIKey
dat = request(cmd)
print(dat)
if dat:find("Invalid API call") then
return nil, "Invalid API call"
else
data[i]=alpha.dataToTable(dat)
data[i].MetaData = {
Symbol = symbols[i],
MostRecentData = data[i].History[1]
}
end
end
return data
end
-- api.TIME_SERIES_INTRADAY
local _interval = {
["1min"]=true,
@ -143,7 +184,7 @@ end
-- api.CURRENCY_EXCHANGE_RATE
function alpha.currencyExchangeRate(from,to)
local dat = https.request("https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency="..from.."&to_currency="..to.."&apikey="..alpha.APIKey)
local dat = request("https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency="..from.."&to_currency="..to.."&apikey="..alpha.APIKey)
if dat:find("Invalid API call") then
return nil, "Invalid API call"
else
@ -162,14 +203,14 @@ local function simpleFXParse(cmd,from,to,interval,outputsize)
outputsize = "&outputsize="..outputsize
end
interval = interval or ""
print("https://www.alphavantage.co/query?function="..cmd.."&from_symbol="..from.."&to_symbol="..to..interval.."&apikey="..alpha.APIKey.."&datatype=csv"..outputsize)
local dat = https.request("https://www.alphavantage.co/query?function="..cmd.."&from_symbol="..from.."&to_symbol="..to..interval.."&apikey="..alpha.APIKey.."&datatype=csv"..outputsize)
local dat = request("https://www.alphavantage.co/query?function="..cmd.."&from_symbol="..from.."&to_symbol="..to..interval.."&apikey="..alpha.APIKey.."&datatype=csv"..outputsize)
if dat:find("Invalid API call") then
return nil, "Invalid API call"
else
local data = alpha.dataToTable(dat)
data.From = from
data.To = to
data.MetaData.From = from
data.MetaData.To = to
data.MetaData.MostRecentData = data.History[1]
return data
end
end
@ -187,11 +228,11 @@ function alpha.currencyExchangeDaily(from,to,outputsize)
end
-- api.FX_WEEKLY
function alpha.currencyExchangeWeekly(from,to,outputsize)
return simpleFXParse("FX_WEEKLY",from,to)
return simpleFXParse("FX_WEEKLY",from,to,nil,outputsize)
end
-- api.FX_MONTHLY
function alpha.currencyExchangeMonthly(from,to,outputsize)
return simpleFXParse("FX_MONTHLY",from,to)
return simpleFXParse("FX_MONTHLY",from,to,nil,outputsize)
end
local function simpleDigitalParse(command,symbols,market)
local data = {}
@ -199,11 +240,14 @@ local function simpleDigitalParse(command,symbols,market)
symbols = {symbols}
end
for i=1,#symbols do
dat = https.request("https://www.alphavantage.co/query?function="..command.."&symbol="..symbols[i].."&market="..market.."&datatype=csv&apikey="..alpha.APIKey)
dat = request("https://www.alphavantage.co/query?function="..command.."&symbol="..symbols[i].."&market="..market.."&datatype=csv&apikey="..alpha.APIKey)
if dat:find("Invalid API call") then
return nil, "Invalid API call"
else
data[symbols[i]]=alpha.dataToTable(dat)
data[symbols[i]].MetaData.Symbol = symbols[i]
data[symbols[i]].MetaData.Market = market
data[symbols[i]].MetaData.MostRecentData = data[symbols[i]].History[1]
end
end
return data
@ -238,11 +282,14 @@ local function technicalParsers(cmd,symbol,interval,time_period,series_type,t)
for i,v in pairs(t or {}) do
extras=extras.."&"..i.."="..v
end
local data = https.request("https://www.alphavantage.co/query?function="..cmd.."&datatype=csv&symbol="..symbol.."&interval="..interval.."&time_period="..time_period.."&series_type="..series_type.."&apikey="..alpha.APIKey..extras)
local data = request("https://www.alphavantage.co/query?function="..cmd.."&datatype=csv&symbol="..symbol.."&interval="..interval.."&time_period="..time_period.."&series_type="..series_type.."&apikey="..alpha.APIKey..extras)
if data:find("Invalid API call") then
return nil, "Invalid API call"
end
return alpha.dataToTable(data)
data = alpha.dataToTable(data)
data.MetaData.Symbol = symbol
data.MetaData.MostRecentData = data.History[1]
return data
end
local function technicalParsers2(cmd,symbol,t)
local extras = ""
@ -250,11 +297,15 @@ local function technicalParsers2(cmd,symbol,t)
extras=extras.."&"..i.."="..v
end
local c = "https://www.alphavantage.co/query?function="..cmd.."&datatype=csv&symbol="..symbol.."&apikey="..alpha.APIKey..extras
local data = https.request(c)
print(c)
local data = request(c)
if data:find("Invalid API call") then
return nil, "Invalid API call"
end
return alpha.dataToTable(data)
data = alpha.dataToTable(data)
data.MetaData.Symbol = symbol
data.MetaData.MostRecentData = data.History[1]
return data
end
-- api.SMA
function alpha.getSMA(symbol,interval,time_period,series_type)
@ -311,7 +362,10 @@ function alpha.getSTOCH(symbol,t)
return technicalParsers2("STOCH",symbol,t)
end
-- api.STOCHF
function alpha.getSTOCHF(symbol,t)
function alpha.getSTOCHF(symbol,interval,t)
local t = t or {
interval = interval or "monthly"
}
return technicalParsers2("STOCHF",symbol,t)
end
-- api.RSI
@ -635,7 +689,7 @@ function alpha.getHTPhasor(symbol,interval,time_period,series_type,t)
end
-- api.SECTOR
function alpha.getSectorPreformance()
local raw = https.request("https://www.alphavantage.co/query?function=SECTOR&apikey="..alpha.APIKey)
local raw = request("https://www.alphavantage.co/query?function=SECTOR&apikey="..alpha.APIKey)
raw=raw:gsub(" ","")
local c = {}
for section,data in raw:gmatch([["(.-)": {.(.-).}]]) do

397
luajit-request/init.lua Normal file
View File

@ -0,0 +1,397 @@
--[[
LuaJIT-Request
Lucien Greathouse
Wrapper for LuaJIT-cURL for easy HTTP(S) requests.
Copyright (c) 2016 Lucien Greathouse
This software is provided 'as-is', without any express
or implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, andto alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
]]
local path = (...):gsub("%.init$", ""):match("%.?(.-)$") .. "."
local ffi = require("ffi")
local curl = require(path .. "luajit-curl")
local request
local function url_encode(str)
if (str) then
str = str:gsub("\n", "\r\n")
str = str:gsub("([^%w %-%_%.%~])", function(c)
return string.format ("%%%02X", string.byte(c))
end)
str = str:gsub(" ", "%%20")
end
return str
end
local function cookie_encode(str, name)
str = str:gsub("[,;%s]", "")
if (name) then
str = str:gsub("=", "")
end
return str
end
local auth_map = {
BASIC = ffi.cast("long", curl.CURLAUTH_BASIC),
DIGEST = ffi.cast("long", curl.CURLAUTH_DIGEST),
NEGOTIATE = ffi.cast("long", curl.CURLAUTH_NEGOTIATE)
}
local errors = {
unknown = 0,
timeout = 1,
connect = 2,
resolve_host = 3
}
local code_map = {
[curl.CURLE_OPERATION_TIMEDOUT] = {
errors.timeout, "Connection timed out"
},
[curl.CURLE_COULDNT_RESOLVE_HOST] = {
errors.resolve_host, "Couldn't resolve host"
},
[curl.CURLE_COULDNT_CONNECT] = {
errors.connect, "Couldn't connect to host"
}
}
request = {
error = errors,
version = "2.4.0",
version_major = 2,
version_minor = 4,
version_patch = 0,
--[[
Send an HTTP(S) request to the URL at 'url' using the HTTP method 'method'.
Use the 'args' parameter to optionally configure the request:
- method: HTTP method to use. Defaults to "GET", but can be any HTTP verb like "POST" or "PUT"
- headers: Dictionary of additional HTTP headers to send with request
- data: Dictionary or string to send as request body
- cookies: Dictionary table of cookies to send
- timeout: How long to wait for the connection to be made before giving up
- allow_redirects: Whether or not to allow redirection. Defaults to true
- body_stream_callback: A method to call with each piece of the response body.
- header_stream_callback: A method to call with each piece of the resulting header.
- transfer_info_callback: A method to call with transfer progress data.
- auth_type: Authentication method to use. Defaults to "none", but can also be "basic", "digest" or "negotiate"
- username: A username to use with authentication. 'auth_type' must also be specified.
- password: A password to use with authentication. 'auth_type' must also be specified.
- files: A dictionary of file names to their paths on disk to upload via stream.
If both body_stream_callback and header_stream_callback are defined, a boolean true will be returned instead of the following object.
The return object is a dictionary with the following members:
- code: The HTTP status code the response gave. Will not exist if header_stream_callback is defined above.
- body: The body of the response. Will not exist if body_stream_callback is defined above.
- headers: A dictionary of headers and their values. Will not exist if header_stream_callback is defined above.
- headers_raw: A raw string containing the actual headers the server sent back. Will not exist if header_stream_callback is defined above.
- set_cookies: A dictionary of cookies given by the "Set-Cookie" header from the server. Will not exist if the server did not set any cookies.
If an error occured, false will be returned along with a curl error code and a message.
]]
send = function(url, args)
local handle = curl.curl_easy_init()
local header_chunk
local out_buffer
local headers_buffer
args = args or {}
local callbacks = {}
local gc_handles = {}
curl.curl_easy_setopt(handle, curl.CURLOPT_URL, url)
curl.curl_easy_setopt(handle, curl.CURLOPT_SSL_VERIFYPEER, 1)
curl.curl_easy_setopt(handle, curl.CURLOPT_SSL_VERIFYHOST, 2)
if (args.data and type(args.data) ~= "table") then
local default_content_type = "application/octet-stream"
if (not args.headers) then
args.headers = {
["content-type"] = default_content_type
}
else
local has_content_type = false
for header_name, _ in pairs(args.headers) do
if header_name:lower() == "content-type" then
has_content_type = true
break
end
end
if not has_content_type then
args.headers["content-type"] = default_content_type
end
end
end
if (args.method) then
local method = string.upper(tostring(args.method))
if (method == "GET") then
curl.curl_easy_setopt(handle, curl.CURLOPT_HTTPGET, 1)
elseif (method == "POST") then
curl.curl_easy_setopt(handle, curl.CURLOPT_POST, 1)
args.data = args.data or "" -- https://github.com/curl/curl/issues/1625#issuecomment-312456910
else
curl.curl_easy_setopt(handle, curl.CURLOPT_CUSTOMREQUEST, method)
end
end
if (args.headers) then
for key, value in pairs(args.headers) do
header_chunk = curl.curl_slist_append(header_chunk, tostring(key) .. ":" .. tostring(value))
end
curl.curl_easy_setopt(handle, curl.CURLOPT_HTTPHEADER, header_chunk)
end
if (args.auth_type) then
local auth = string.upper(tostring(args.auth_type))
if (auth_map[auth]) then
curl.curl_easy_setopt(handle, curl.CURLOPT_HTTPAUTH, auth_map[auth])
curl.curl_easy_setopt(handle, curl.CURLOPT_USERNAME, tostring(args.username))
curl.curl_easy_setopt(handle, curl.CURLOPT_PASSWORD, tostring(args.password or ""))
elseif (auth ~= "NONE") then
error("Unsupported authentication type '" .. auth .. "'")
end
end
if (args.body_stream_callback) then
local callback = ffi.cast("curl_callback", function(data, size, nmeb, user)
args.body_stream_callback(ffi.string(data, size * nmeb))
return size * nmeb
end)
table.insert(callbacks, callback)
curl.curl_easy_setopt(handle, curl.CURLOPT_WRITEFUNCTION, callback)
else
out_buffer = {}
local callback = ffi.cast("curl_callback", function(data, size, nmeb, user)
table.insert(out_buffer, ffi.string(data, size * nmeb))
return size * nmeb
end)
table.insert(callbacks, callback)
curl.curl_easy_setopt(handle, curl.CURLOPT_WRITEFUNCTION, callback)
end
if (args.header_stream_callback) then
local callback = ffi.cast("curl_callback", function(data, size, nmeb, user)
args.header_stream_callback(ffi.string(data, size * nmeb))
return size * nmeb
end)
table.insert(callbacks, callback)
curl.curl_easy_setopt(handle, curl.CURLOPT_HEADERFUNCTION, callback)
else
headers_buffer = {}
local callback = ffi.cast("curl_callback", function(data, size, nmeb, user)
table.insert(headers_buffer, ffi.string(data, size * nmeb))
return size * nmeb
end)
table.insert(callbacks, callback)
curl.curl_easy_setopt(handle, curl.CURLOPT_HEADERFUNCTION, callback)
end
if (args.transfer_info_callback) then
local callback = ffi.cast("curl_xferinfo_callback", function(client, dltotal, dlnow, ultotal, ulnow)
args.transfer_info_callback(tonumber(dltotal), tonumber(dlnow), tonumber(ultotal), tonumber(ulnow))
return 0
end)
table.insert(callbacks, callback)
curl.curl_easy_setopt(handle, curl.CURLOPT_NOPROGRESS, 0)
curl.curl_easy_setopt(handle, curl.CURLOPT_XFERINFOFUNCTION, callback)
end
if (args.follow_redirects == nil) then
curl.curl_easy_setopt(handle, curl.CURLOPT_FOLLOWLOCATION, true)
else
curl.curl_easy_setopt(handle, curl.CURLOPT_FOLLOWLOCATION, not not args.follow_redirects)
end
if (args.data) then
if (type(args.data) == "table") then
local buffer = {}
for key, value in pairs(args.data) do
table.insert(buffer, ("%s=%s"):format(url_encode(key), url_encode(value)))
end
curl.curl_easy_setopt(handle, curl.CURLOPT_POSTFIELDS, table.concat(buffer, "&"))
else
curl.curl_easy_setopt(handle, curl.CURLOPT_POSTFIELDS, tostring(args.data))
end
end
local post
if (args.files) then
post = ffi.new("struct curl_httppost*[1]")
local lastptr = ffi.new("struct curl_httppost*[1]")
for key, value in pairs(args.files) do
local file = ffi.new("char[?]", #value, value)
table.insert(gc_handles, file)
local res = curl.curl_formadd(
post, lastptr,
ffi.new("int", curl.CURLFORM_COPYNAME), key,
ffi.new("int", curl.CURLFORM_FILE), file,
ffi.new("int", curl.CURLFORM_END)
)
end
curl.curl_easy_setopt(handle, curl.CURLOPT_HTTPPOST, post[0])
end
-- Enable the cookie engine
curl.curl_easy_setopt(handle, curl.CURLOPT_COOKIEFILE, "")
if (args.cookies) then
local cookie_out
if (type(args.cookies) == "table") then
local buffer = {}
for key, value in pairs(args.cookies) do
table.insert(buffer, ("%s=%s"):format(cookie_encode(key, true), cookie_encode(value)))
end
cookie_out = table.concat(buffer, "; ")
else
cookie_out = tostring(args.cookies)
end
curl.curl_easy_setopt(handle, curl.CURLOPT_COOKIE, cookie_out)
end
if (tonumber(args.timeout)) then
curl.curl_easy_setopt(handle, curl.CURLOPT_CONNECTTIMEOUT, tonumber(args.timeout))
end
local code = curl.curl_easy_perform(handle)
if (code ~= curl.CURLE_OK) then
local num = tonumber(code)
if (code_map[num]) then
return false, code_map[num][1], code_map[num][2]
end
return false, request.error.unknown, "Unknown error", num
end
local out
if (out_buffer or headers_buffer) then
local headers, status, parsed_headers, raw_cookies, set_cookies
if (headers_buffer) then
-- In case we got multiple responses (e.g. 100 - Continue or 302 Redirects)
-- we want to only return the last response
local start_index = 1
for i, resp_line in ipairs(headers_buffer) do
if resp_line:match("^HTTP/(.-)%s+(%d+)%s+(.+)\r\n$") then
start_index = i
end
end
local last_request_headers = {}
for i = start_index, #headers_buffer do
table.insert(last_request_headers, headers_buffer[i])
end
headers = table.concat(last_request_headers)
status = tonumber(headers:match("%s+(%d+)%s+"))
parsed_headers = {}
for key, value in headers:gmatch("\n([^:]+): *([^\r\n]*)") do
parsed_headers[key] = value
end
end
local cookielist = ffi.new("struct curl_slist*[1]")
curl.curl_easy_getinfo(handle, curl.CURLINFO_COOKIELIST, cookielist)
if cookielist[0] ~= nil then
raw_cookies, set_cookies = {}, {}
local cookielist = ffi.gc(cookielist[0], curl.curl_slist_free_all)
local cookie = cookielist
repeat
local raw = ffi.string(cookie[0].data)
table.insert(raw_cookies, raw)
local domain, subdomains, path, secure, expiration, name, value = raw:match("^(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.*)$")
set_cookies[name] = value
cookie = cookie[0].next
until cookie == nil
end
out = {
body = table.concat(out_buffer),
headers = parsed_headers,
raw_cookies = raw_cookies,
set_cookies = set_cookies,
code = status,
raw_headers = headers
}
else
out = true
end
curl.curl_easy_cleanup(handle)
curl.curl_slist_free_all(header_chunk)
if (post) then
curl.curl_formfree(post[0])
end
gc_handles = {}
for i, v in ipairs(callbacks) do
v:free()
end
return out
end,
init = function()
curl.curl_global_init(curl.CURL_GLOBAL_ALL)
end,
close = function()
curl.curl_global_cleanup()
end
}
request.init()
return request

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,8 @@ returns a list of Physical Currencies
#alpha.getDigitalCurrencyList(boolean: force)
returns a list of Digital Currencies
**Note:** The above 2 function have a table format of key: "currency code" val: "name of currency". Also these functions also cache a file containing a list of currencies. Setting force to true will force the function to request a list of currencies again.
#alpha.globalQuote(symbols)
returns the current price and metadata of a stock or a table of stocks
#alpha.timeSeriesDaily(symbols, outputsize)
#alpha.timeSeriesDailyAdjusted(symbols,outputsize)
#alpha.timeSeriesWeekly(symbols,outputsize)