在谷歌表格上创建加密货币投资组合跟踪器(使用应用程序脚本)
特别是在像加密货币这样快速发展的领域,全天候掌握投资情况可能会让人不知所措。在这篇文章中,我们将分享如何使用谷歌表格构建自己的实时投资组合跟踪器,以便您可以轻松管理和跟踪您的加密货币投资。创建自己的自定义投资组合将允许您记录和计算您的加密货币持有量,分析加密货币价格和数量变化,并根据您的交易偏好进行定制。交易股票和其他资产的投资者甚至可以将其与现有的股票投资组合跟踪器相结合。
无论您是初学者还是高级交易者,本详细指南都将逐步介绍:
- 如何设置您的Google表格进行自动刷新
- 如何通过导入实时加密数据CoinGecko API(适用于演示和付费API用户)
- 如何自定义电子表格以计算加密货币持有量、持有价值等
- 在谷歌表格上创建投资组合跟踪器的好处
让我们开始吧!
步骤1:使用应用程序脚本导入实时加密货币价格数据
首先,在新的电子表格中,导航到“扩展'并选择'应用程序脚本'-将出现一个新选项卡。
在左侧面板上,选择“<>;编辑器'并使用'添加新脚本+“按钮。复制并粘贴以下importJSON脚本,并将脚本另存为“导入JSON’. ;这个importJSON脚本是一个多功能的脚本,它允许您以多种不同的方式导入数据。
/*====================================================================================================================================*Brad Jasper和Trevor Lohrbeer的ImportJSON====================================================================================================================================版本:1.5.0项目页面:https://github.com/bradjasper/ImportJSON版权所有:(c)2017-2019作者:Brad Jasper(c) 2012-2017作者:特雷弗·洛尔贝尔许可证:GNU通用公共许可证,版本3(GPL-3.0)http://www.opensource.org/licenses/gpl-3.0.html------------------------------------------------------------------------------------------------------------------------------------一个用于将JSON提要导入Google电子表格的库。功能包括:ImportJSON供最终用户从URL导入JSON提要ImportJSONFromSheet供最终用户从其中一个表中导入JSONImportJSONViaPost供最终用户使用POST参数从URL导入JSON提要ImportJSONAdvanced供脚本开发人员使用,以轻松扩展此库的功能ImportJSONBasicAuth供最终用户使用HTTP Basic Auth从URL导入JSON提要(由Karsten Lettow添加)有关未来的增强功能,请参阅https://github.com/bradjasper/ImportJSON/issues?q=is%3Aissue+是%3开放+标签%3增强有关错误报告,请参阅https://github.com/bradjasper/ImportJSON/issues------------------------------------------------------------------------------------------------------------------------------------变更日志:1.6.0(2019年6月2日)修复了空值(感谢@gdesmedt1)1.5.0(2019年1月11日)添加了以固定顺序包含所有标题的功能,即使在某些或所有行中没有给定标题的数据。1.4.0(7月23日2017)将项目转让给Brad Jasper。修复了一个数组错误。修复了之前的值错误。添加了自定义注释。添加了ImportJSONFromSheet和ImportJSONBasicAuth。1.3.0添加了从包含要解析的文本的一组行中导入文本的功能。所有单元格都连接在一起1.2.1修复了嵌套数组处理方式的错误。分析时rowIndex计数器没有正确递增。1.2.0为ImportJSONAdvanced添加了ImportJSONViaPost和fetchOptions支持1.1.1使用Google脚本版本控制添加了版本号,以便其他开发人员可以使用该库1.1.0添加了对无标题选项的支持1.0.0初始版本*====================================================================================================================================*//***导入JSON提要并返回结果以插入到Google电子表格中。JSON提要被展开以创建*二维阵列。第一行包含标题,每个列标题指示该数据的路径*JSON提要。其余行包含数据。* *默认情况下,数据会被转换,使其看起来更像正常的数据导入。明确地:**-父JSON元素的数据被继承到它们的子元素,因此表示子元素的行包含这些值*代表其父元素的行。*-长度超过256个字符的值将被截断。*-标题将斜线转换为空格,删除常见前缀,并将生成的文本转换为标题大小写。**要更改此行为,请在options参数中传入以下值之一:**noInherit:不从父元素继承值*无截断:不截断值*rawHeaders:不要美化标题*无标题:不包含标题只有数据*allHeaders:按列出顺序包含查询参数中的所有标头*debugLocation:在每个值前面加上行&;它所属的列**例如:**=导入JSON(“http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&;alt=json“,”/feed/entry/title,/feed/eentry/content“,*“noInherit、noTruncate、rawHeaders”)* *@param{url}公共JSON提要的url*@param{query}一个逗号分隔的导入路径列表。任何以这些路径之一开头的路径都会被导入。*@param{parseOptions}一个逗号分隔的选项列表,用于更改数据处理*@自定义函数**@返回一个包含数据的二维数组,第一行包含标题**/函数ImportJSON(url、查询、parseOptions){返回ImportJSONAdvanced(url、null、查询、parseOptions、includeXPath_、defaultTransform_);}/***通过POST请求导入JSON提要,并返回结果以插入Google电子表格。JSON提要是*展开以创建二维数组。第一行包含标题,每一列标题指示到的路径*JSON提要中的数据。其余行包含数据。**为了检索JSON,向URL发送POST请求,并使用内容将有效载荷作为请求的内容传递*键入“应用程序/x-www-form-urlencoded”。如果fetchOptions为“method”、“payload”或“contentType”定义了一个值,则这些*价值观将成为先例。例如,高级用户可以使用它使此函数使用GET将XML作为有效载荷传递*请求和内容类型“application/xml;字符集=utf-8”。有关可用获取选项的更多信息,请参阅* https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app . 目前不支持“headers”选项。* *默认情况下返回的数据经过转换,看起来更像是正常的数据导入。明确地:**-父JSON元素的数据被继承到它们的子元素,因此表示子元素的行包含这些值*代表其父元素的行。*-长度超过256个字符的值将被截断。*-标题将斜线转换为空格,删除常见前缀,并将生成的文本转换为标题大小写。**要更改此行为,请在options参数中传入以下值之一:**noInherit:不从父元素继承值*noTruncate:不截断值*rawHeaders:不要美化标题*noHeaders:不包括标头,只包括数据*allHeaders:按列出顺序包含查询参数中的所有标头*debugLocation:在每个值前面加上行&;它所属的列**例如:**=导入JSON(“http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&;alt=json“,”user=bob&;apikey=xxxx”,*“validateHttpsCertificates=false”,“/feed/intry/title,/feed/index/content”,“noInherit,noTruncate,rawHeaders”)* *@param{url}公共JSON提要的url*@param{payload}与POST请求一起传递的内容;通常是用与号分隔的URL编码的参数列表*@param{fetchOptions}一个逗号分隔的选项列表,用于从URL检索JSON提要*@param{query}一个逗号分隔的导入路径列表。任何以这些路径之一开头的路径都会被导入。*@param{parseOptions}一个逗号分隔的选项列表,用于更改数据处理*@自定义函数**@返回一个包含数据的二维数组,第一行包含标题**/函数ImportJSONViaPost(url、有效载荷、fetchOptions、查询parseOptions){var postOptions=parseToObject_(fetchOptions);if(postOptions[“method”]==null){postOptions[“method”]=“POST”;}if(postOptions[“payload”]==null){postOptions[“payload”]=有效载荷;}if(postOptions[“contentType”]==空){postOptions[“contentType”]=“应用程序/x-www-form-urlencoded”;}convertToBool_(postOptions,“验证HTTP证书”);convertToBool_(postOptions,“useIntranet”);convertToBool_(postOptions,“followRedirects”);convertToBool_(postOptions,“muteHttpExceptions”);返回ImportJSONAdvanced(url、postOptions、query、parseOptions、includeXPath_、defaultTransform_);}/***从命名的表格中导入JSON文本,并返回结果以插入到Google电子表格中。JSON提要被展开以创建*二维阵列。第一行包含标题,每个列标题指示该数据的路径*JSON提要。其余行包含数据。* *默认情况下,数据会被转换,使其看起来更像正常的数据导入。明确地:**-父JSON元素的数据被继承到它们的子元素,因此表示子元素的行包含这些值*代表其父元素的行。*-长度超过256个字符的值将被截断。*-标题将斜线转换为空格,删除常见前缀,并将生成的文本转换为标题大小写。**要更改此行为,请在options参数中传入以下值之一:**noInherit:不从父元素继承值*noTruncate:不截断值*rawHeaders:不要美化标题*noHeaders:不包括标头,只包括数据*allHeaders:按列出顺序包含查询参数中的所有标头*debugLocation:在每个值前面加上行&它所属的列**例如:**=ImportJSONFromSheet(“源代码”、“/feed/entry/title、/feed/eentry/content”,*“noInherit、noTruncate、rawHeaders”)* *@param{sheetName}包含JSON文本的工作表的名称*@param{query}一个逗号分隔的导入路径列表。任何以这些路径之一开头的路径都会被导入。*@param{options}一个逗号分隔的选项列表,用于更改数据处理**@返回一个包含数据的二维数组,第一行包含标题*@自定义函数**/函数ImportJSONFromSheet(表名、查询、选项){var对象=getDataFromNamedSheet_(sheetName);返回parseJSONObject_(对象、查询、选项,包括xPath_、defaultTransform_);}/***ImportJSON的高级版本,旨在通过脚本轻松扩展。无法从内部调用此版本*电子表格。* *导入JSON提要并返回结果以插入到Google电子表格中。JSON提要被展开以创建*二维阵列。第一行包含标题,每个列标题指示该数据的路径*JSON提要。其余行包含数据。**fetchOptions可用于更改JSON提要的检索方式。例如,“方法”和“有效载荷”选项可以是*设置为传递带有POST参数的POST请求。有关可用参数的更多信息,请参阅* https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app .**使用包含和转换函数来确定导入中要包含的内容以及导入后如何转换数据*进口。**例如:**导入JSON(“http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&;alt=json”,*new Object(){“method”:“post”,“payload”:“user=bob&;apikey=xxxx”},*“/馈送/输入”* "",*函数(query,path){返回path.indexOf(query)==0;},*函数(data,row,column){data[row][column]=data[row][column].toString().subr(0100);})**在这个例子中,import函数检查要导入的数据的路径是否以查询开头。转变*函数获取数据并截断它。有关这些函数的更健壮版本,请参阅此库的内部代码。**@param{url}公共JSON提要的url*@param{fetchOptions}一个对象,其属性是用于从URL检索JSON提要的选项*@param{query}传递给include函数的查询*@param{parseOptions}一个逗号分隔的选项列表,可能会改变数据的处理*@param{includeFunc}一个具有签名func(查询、路径、选项)的函数,如果给定路径上的数据元素为true,则返回true*应包括在内,否则为假。*@param{transformFunc}一个具有签名func(数据、行、列、选项)的函数,其中数据是数据的二维数组*行和;列是当前正在处理的行和列。任何返回值都将被忽略。请注意,第0行*包含数据的标头,因此测试行==0仅处理标头。**@返回一个包含数据的二维数组,第一行包含标题*@自定义函数**/函数ImportJSONAdvanced(url、fetchOptions、query、parseOptions、includeFunc、transformFunc){var jsondata=UrlFetchApp.fetch(url,fetchOptions);var对象=JSON.parse(jsondata.getContentText());返回parseJSONObject_(对象、查询、parseOptions、includeFun、transformFunc)}/***使用ImportJSONAdvanced使用基本身份验证信息进行身份验证的帮助函数**导入JSON提要并返回结果以插入到Google电子表格中。JSON提要被展开以创建*二维阵列。第一行包含标题,每个列标题指示该数据的路径*JSON提要。其余行包含数据。**fetchOptions可用于更改JSON提要的检索方式。例如,“方法”和“有效载荷”选项可以是*设置为传递带有POST参数的POST请求。有关可用参数的更多信息,请参阅* https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app .**使用包含和转换函数来确定导入中要包含的内容以及导入后如何转换数据*进口。**@param{url}指向http基本身份验证保护的JSON提要的url*@param{username}用于身份验证的用户名*@param{password}身份验证密码*@param{query}传递给include函数的查询(可选)*@param{parseOptions}一个逗号分隔的选项列表,可能会改变数据的处理(可选)**@返回一个包含数据的二维数组,第一行包含标题*@自定义函数**/函数ImportJSONBasicAuth(url、用户名、密码、查询、parseOptions){var encodedAuthInformation=实用程序。base64Encode(用户名+“:”+密码);var header={headers:{授权:“基本”+encodedAuthInformation};返回ImportJSONAdvanced(url、header、query、parseOptions、includeXPath_、defaultTransform_);}/** *对给定值进行编码,以便在URL中使用。**@param{value}要编码的值* *@返回使用URL百分比编码的值*/函数URL编码(值){返回encodeURIComponent(value.toString())}/***使用给定的名称和属性列表添加oAuth服务。**@note这个方法是一个实验,试图弄清楚如何添加oAuth服务,而不必在每个服务上都指定它*导入JSON调用。其想法是在电子表格的第一个单元格中调用此方法,然后在其他单元格中使用ImportJSON*细胞。这不起作用,但把它留在这里供以后进一步实验。**我做的测试是在A1中添加以下内容:* *=AddOAuthService(“推特”,“https://api.twitter.com/oauth/access_token", * "https://api.twitter.com/oauth/request_token", "https://api.twitter.com/oauth/authorize", *“<;我的消费者密钥>;”、“<;消费者机密>;”)**关于获取消费者密钥的信息;推特的秘密可以在以下网址找到https://dev.twitter.com/docs/auth/using-oauth**然后我在A2中添加了以下内容:**=导入JSONViaPost(“https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=fastfedora&;计数=2“,”“,*“oAuthServiceName=推特,oAuthUseToken=始终”,“/”,“”)**我收到一个错误,即“oAuthServiceName”不是有效值。[twl 18.四月13]*/函数AddOAuthService__(名称、访问令牌URL、请求令牌URL、授权URL、消费者密钥、消费者秘密、方法、参数位置){var oAuthConfig=UrlFetchApp.addOAuthService(名称);if(accessTokenUrl!=null&;&;accessTokenUrl.length>;0){oAuthConfig.setAccessTokenUrl(accessTokenUrl);}if(requestTokenUrl!=null&;amp;requestTokenUrl.length>;0){oAuthConfig.setRequestTokenUrl(requestTokenUrl);}if(authorizationUrl!=空&;&;authorizationUrl.length>;0){oAuthConfig.setAuthorizationUrl(授权URL);}if(consumerKey!=空&;amp;amp消费者密钥长度>;0) {oAuthConfig.setSumerKey(consumerKey);}if(consumerSecret!=空&;&;consumerSecult.length>;0){oAuthConfig.setSumerSecret(consumerSecret);}if(方法!=null&;&method.length>;0){oAuthConfig.setMethod(方法);}if(paramLocation!=null&;amp;paramLocation.length>;0){oAuthConfig.setParamLocation(paramLocation);}}/** *解析JSON对象并返回包含该对象数据的二维数组。*/函数parseJSONObject_(对象、查询、选项、includeFunc、transformFunc){var headers=new Array();var数据=新数组();if(查询&;&;!Array.isArray(查询)&&;query.toString().indexOf(“,”)!=-1.query=query.toString().split(“,”);}//预填充标题以锁定其顺序if(hasOption_(选项,“allHeaders”)&&;Array.isArray(查询)){for(var i=0;i<;query.length;i++){headers[query[i]]=Object.keys(headers).length;}}if(选项){options=options.toString().split(“,”);}parseData_(标头、数据、“”、{rowIndex:1}、对象、查询、选项、includeFunc);parseHeaders_(标头、数据);transformData_(数据、选项、transformFunc);return hasOption_(选项,“noHeaders”)?(data.length>1?data.slice(1):new Array()):数据;}/** *解析给定值中包含的数据,并将其插入到从rowIndex开始的数据二维数组中。*如果要将数据插入到新列中,则会在headers数组中添加一个新的header。该值可以是对象,*数组或标量值。**如果该值是一个对象,则其属性会被迭代并传递回此函数,并带有每个对象的名称*属性延伸路径。例如如果对象包含属性“entry”,并且传入的路径是“/feed”,*使用entry属性的值和路径“/feed/entry”调用此函数。**如果该值是一个包含其他数组或对象的数组,则数组中的每个元素都将通过以下方式传递到此函数中*rowIndex为每个元素递增。**如果该值是一个仅包含标量值的数组,则这些值将连接在一起并插入到数据数组中,如下所示*一个单一的值。**如果该值是标量,则该值将直接插入到数据数组中。*/函数parseData_(标头、数据、路径、状态、值、查询、选项、includeFunc){var数据插入=false;if(Array.isArray(value)&&;isObjectArray_(值)){for(var i=0;i<;value.length;i++){if(parseData_(标头、数据、路径、状态、值[i]、查询、选项、includeFunc)){dataInserted=true;if(数据[state.rowIndex]){state.rowIndex++;}}}}else if(isObject_(value)){for(键入值){if(parseData_(标头、数据、路径+“/”+键、状态、值[key]、查询、选项、includeFunc)){dataInserted=true;}}}else if(!includeFun|| includeFun(查询、路径、选项)){//处理仅包含标量值的数组if(Array.isArray(value)){value=value.join();}//如果新行不存在,则插入新行if(!data[state.rowIndex]){data[state.rowIndex]=new Array();}//如果不存在,请添加新标题如果(!headers[path]&;amp;headers[path]!=0){headers[path]=Object.keys(headers).length;}//插入数据data[state.rowIndex][headers[path]]=值;dataInserted=true;}返回数据已插入}/** *解析headers数组并将其插入数据数组的第一行。*/函数parseHeaders_(标头、数据){data[0]=新数组();for(键入标题){data[0][headers[key]]=key;}}/** *对数据数组中的每个元素应用转换函数,遍历每行的每一列。*/函数转换data_(数据、选项、转换函数){for(变量i=0;i<;数据长度;i++){for(var j=0;j<;data[0].length;j++){transformFunc(数据、i、j、选项);}}}/** *如果给定的测试值是一个对象,则返回true;否则为假。*/函数isObject_(测试){return Object.prototype.toString.call(test)===“[Object Object]”;}/** *如果给定的测试值是一个包含至少一个对象的数组,则返回true;否则为假。*/函数isObjectArray_(测试){for(var i=0;i<;test.length;i++){if(isObject_(test[i])){返回true;}} 返回false;}/** *如果给定的查询应用于给定的路径,则返回true。*/函数includeXPath_(查询、路径、选项){if(!query){返回true;}else if(Array.isArray(查询)){for(var i=0;i<;query.length;i++){if(applyXPathRule_(查询[i],路径,选项)){返回true;}} }其他{返回applyXPathRule_(查询、路径、选项);}返回false;};/** *如果规则适用于给定路径,则返回true。*/函数applyXPathRule_(规则、路径、选项){返回path.indexOf(rule)==0;}/** *默认情况下,此函数转换给定行的值&;列,因此它看起来更像是一个正常的数据导入。明确地:**-父JSON元素的数据被继承到其子元素因此,表示子元素的行包含这些值*代表其父元素的行。*-长度超过256个字符的值将被截断。*-第0行(标题)中的值将斜线转换为空格,删除常见前缀,并将结果文本转换为标题*案件。**要更改此行为,请在options参数中传入以下值之一:**noInherit:不从父元素继承值*noTruncate:不截断值*rawHeaders:不要美化标题*debugLocation:在每个值前面加上行&;它所属的列*/函数defaultTransform_(数据、行、列、选项){if(数据[行][列]==空){if(行<;2|| hasOption_(选项,“noInherit”)){data[行][列]=“”;}其他{data[行][列]=data[行-1][列];}} if(!hasOption_(options,“rawHeaders”)&&;行==0){if(列==0&;数据[行].length>;1){removeCommonPrefixs_(数据,行);}data[row][column]=toTitleCase_(data[row][column].toString().replace(/[\/\_]/g,“”);}if(!hasOption_(选项,“noTruncate”)&&;数据[行][列]){data[row][column]=data[row][column].toString().subr(0256);}if(hasOption_(选项,“debugLocation”){data[行][列]=“[”+行+“,”+列+“]”+data[行][列];}}/** *如果给定行中的所有值共享相同的前缀,请删除该前缀。*/函数removeCommonPrefixs_(数据,行){var matchIndex=数据[row][0].length;for(var i=1;i<;data[row].length;i++){matchIndex=findEqualityEndpoint_(数据[row][i-1],数据[row][i],matchIndex);if(matchIndex==0){回归;}}for(var i=0;i<;data[row].length;i++){data[row][i]=data[row][i].substring(matchIndex,data[row][i].length)}}/** *定位两个字符串值不再相等的索引,在stopAt索引处自动停止。*/函数findEqualityEndpoint_(字符串1、字符串2、stopAt){if(!string1||!string2){return-1;}var maxEndpoint=Math.min(stopAt,string1.length,string2.length);for(var i=0;i<;maxEndpoint;i++){if(string1.charAt(i)!=string2.charAt(i)){返回i;}}返回maxEndpoint;}/** *将文本转换为标题大小写。*/函数为TitleCase_(文本){if(文本==空){返回null;}return text.replace(/\w\S*/g,函数(word){返回word.charAt(0).toPercase()+word.strl(1).toLowerCase();});}/** *如果给定的选项集包含给定的选项,则返回true。*/函数hasOption_(选项,选项){返回选项&&;options.indexOf(选项)>;=0;}/** *将给定的字符串解析为对象,修剪键的任何前导或尾随空格。*/函数parseToObject_(文本){var映射=新对象();var entries=(text!=null&;&text.crim().length>;0) ? text.toString().split(“,”):new Array();for(变量i=0;i<;条目长度;i++){addToMap_(地图,条目[i]);}返回图;}/** *解析给定的条目并将其添加到给定的映射中,修剪键的任何前导或尾随空格。*/函数addToMap_(地图,条目){var等于index=entry.indexOf(“=”);var键=(等于索引!=-1)?entry.substring(0,equalsIndex):条目;var值=(key.length+1<;entry.length)?entry.substring(key.length+1):“”;map[key.trim()]=值;}/** *将给定值作为布尔值返回。*/函数toBool_(值){返回值==null?false:(value.toString().toLowerCase()==“true”?真:假)复制
通过单击“”创建第二个应用程序脚本+“按钮。复制下面的代码并将其粘贴到脚本编辑器中,将其另存为“自动刷新'–这将允许您的工作表以固定的时间间隔自动刷新。
/***Vadorequest的此函数在“randomNumber”表中生成一个随机数。**它需要在以下位置用谷歌应用程序脚本触发器触发https://script.google.com/home/:*-选择项目并添加触发器*-选择要运行的功能:triggerAutoRefresh*-选择事件源:时间驱动*-选择基于时间的触发器类型:分钟计时器*-选择分钟间隔:10分钟(以避免请求过多)**///用随机数更新“randomNumber”中的单元格A1函数触发器AutoRefresh(){电子表格App.getActive().getSheetByName('doNotDelete”).getRange(1,1).setValue(getRandomInt(1200));}//基本Math.random()函数函数getRandomInt(最小,最大){min=数学.ceil(min);max=数学下限(max);返回Math.floor(Math.random()*(max-min+1))+min;}复制
您的应用程序脚本编辑器现在看起来像这样:
为了使应用程序脚本无错误地工作,请务必创建一个空表(选项卡)并将其标记为“doNotDelete”。
步骤2:使用触发器自动刷新数据
现在脚本已经创建,选择左侧的时钟图标导航到“触发器’.
点击'+添加触发器'将导致出现此弹出窗口。相应地选择相应的下拉菜单:
- 选择要运行的功能:触发器自动刷新
- 选择应运行的部署:校长
- 选择事件源:时间驱动
- 选择基于时间的触发器类型:分钟计时器
- 选择分钟间隔:每5或10分钟(注意:小于此值的任何内容都可能没有用,因为结果会被缓存)
根据您的首选频率,您还可以在小时计时器、日计时器、周计时器和15或30分钟间隔触发器之间切换。
步骤3:使用CoinGecko API导入500强加密数据
CoinGecko追踪1100多种加密货币中的16000多种加密货币;交易所,是全球数百万投资者和交易员的首选来源。硬币排名是基于市值的,因此对大多数人来说,获取前500名加密货币的数据通常就足够了。如果您交易市值较小的硬币,请相应地调整参数!
前往/硬币/市场API文档中的端点。
如果您手头有API密钥,您可以使用自述游乐场生成响应。请记住根据您的计划和密钥身份验证参考正确的文档版本。公共API;拥有演示密钥的用户;应参考v3.0.1,付费API(专业密钥)用户应参考v3.1.1;
每一个“第页“追踪250枚硬币,我们将通过两个API调用导入两页硬币数据,以获得前500种加密货币。离开'ids'参数为空,并添加以下输入:
- 每页:250
- 页码: 1
相应地填写剩余的查询参数,在下输入您的API键'身份验证'然后,单击试试我不是。
要提取小盘硬币的数据,请相应地更改页码——例如,您将导入排名在#2500到#3000之间的硬币的硬币数据,并使用“第页参数输入为11和12。这也将消耗两个API调用。
在我们的示例中,请求URL为:
https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&订单=market_cap_desc&;每页=250&;第1页;火花线=真;价格变动百分比=1h%2C24h%2C7d&;locale=en&;精度=3
复制此内容并返回工作表。
标记新工作表'前500名硬币,因为这将作为您的原始数据库,而不是您实际的加密货币投资组合仪表板。
In单元格A1,使用以下内容并替换请求URL因此。
=导入json(“请求URL“,”/name,/current_price,/market_cap,/价格变更,/总计_体积,/高24小时,/low_24h“,”无截断,无标题“,不删除$A 1美元)
将出现以下脚本:
=导入json(“https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&订单=market_cap_desc&;每页=100&;第1页;火花线=真;价格变动百分比=1h%2C24h%2C7d&;locale=en&;精度=3?x_cg_demo_api_key=YOUR_api_key”,“/name,/current_price,/market_cap,/price_change,/total_volume,/high_24h,/low_24h”,“no截断”,doNotDelete$A 1美元)
别忘了;提供您的演示;API通过查询字符串参数指向根URL的键。
加载脚本后,排名前250位的加密货币及其各自的价格、市值数据将通过第251行流式传输到您的电子表格中。
- /姓名–硬币名称
- /当前价格–硬币价格
- /market_cap–所有市值详情
- /price_change–24小时价格变动
- /total_volume–24小时交易量
- /high_24h和/低24–24小时价格高低
要提取接下来的250种加密货币,请对以下内容应用相同的公式细胞A252只需稍作调整,或简单地复制并粘贴公式;在......下面
- 将页码更改为“2',因为我们现在要转到第2页,了解前251-500种加密货币
- 加载项',无标题“之后”noTruncate“-这可以防止重复第252行的标题(如第1行所示)。
演示;API用户:
=导入json(“https://api.coingecko.com/api/v3/硬币/市场?vs_currency=美元;订单=market_cap_desc&;每页=250&;页面=2&;火花线=真;价格变动百分比=1h%2C24h%2C7d&;locale=en&;精度=3?x_cg_demo_api_key=YOUR_api_key“,”/name,/current_price,/market_cap,/price_change,/total_volume,/high_24h,/low_24h“,”无截断,noHeaders“,不要删除$A 1美元)
同样,由于Google Sheets和Demo API速率限制,您可能只能导入有限范围的数据。
API付费用户:
=导入json(“https://pro-api.coingecko.com/api/v3/硬币/市场?vs_currency=美元;订单=market_cap_desc&;每页=250&;页面=2&;火花线=真;价格变动百分比=1h%2C24h%2C7d&;locale=en&;精度=3?&;x_cg_pi_key=YOUR_API键“,”/name,/current_price,/market_cap,/price_change,/total_volume,/high_24h,/low_24h“,”无截断,noHeaders“,不要删除$A 1美元)
Google Sheets上强大的加密货币API集成使您能够轻松获取CoinGecko上排名前500的加密货币的实时价格,数据自动刷新;每10分钟。
获取特定加密货币的数据
在您只想检索特定硬币列表的数据的情况下,您可以填写“ids'带有相应硬币的参数'API ID–此代币API列表,由CoinGecko团队创建的,特别有用。或者,您可以在CoinGecko并复制API id从各个硬币页面。例如,XRP的API id为涟漪’.
在“ids”参数中的“ripple”中过滤;然后选择“试试看!”。将相应地生成响应。
我们将进入最后一步,您可以在那里定制您的加密货币投资组合跟踪器和仪表板。
步骤4:创建您的加密货币投资组合跟踪器
现在您有了前500种加密货币的自动更新数据库,您可以根据您的交易偏好自定义您的投资组合跟踪器。
使用VLOOKUP,根据硬币名称搜索价格、市值、交易量和百分比变化。在这个例子中,我们做了一个VLOOKUP搜索“比特币'inB19单元,在前500名硬币工作表。
由于硬币价格数据在第2栏在我们的500强硬币数据库中,我们输入“2在VLOOKUP公式中。
此方法应用于表的其余部分,并相应地返回响应值。
最后,在末尾创建一个投资组合部分来跟踪您的持有量,根据实时加密货币价格计算持有价值和损益(P&L)。
创建以下行标题:
- 当前持股-你目前持有的每枚硬币的多少。
- 当前持有价值(美元)–您的加密货币持有价值是多少,以法定货币计算,通过将当前持有量乘以当前价格得出。
- 总投资(美元)–每次入场的法定货币购买成本。
- 未实现损益;L(美元)–如果当时关闭头寸,可以实现的利润或亏损。
- 已实现损益;L(美元)–基于收盘头寸已实现的实际损益。
- 投资回报率%–投资回报率,评估您的投资效率或盈利能力。您的投资回报率越高,您的投资盈利能力就越强。
最后,您可能希望将数据可视化添加到您的加密货币投资组合跟踪器中。添加图表和摘要可以帮助以易于理解的方式组织和展示您的加密货币投资,特别是如果您的篮子里有各种各样的加密货币资产。
当你继续投资加密货币时,你需要用新的购买记录更新你的投资组合跟踪器,并删除过时的记录。虽然本文没有完全涵盖计算交易损益,但我们很快就会创建一个分步指南;如何实现P&;L——未实现、已实现、投资回报率等。
这是决赛;谷歌表格上的加密货币投资组合跟踪器;通过应用程序脚本和CoinGecko API:
在谷歌表格上跟踪您的加密货币投资组合的好处
在谷歌表格上跟踪您的加密货币投资组合,使您能够随时随地通过图表、数据透视表和公式轻松分析任何设备上的数据。 拥有实时加密货币价格数据还可以确保;你随时都能准确地了解你的所有投资。在加密货币、股票和其他使用谷歌表格的资产上分散投资组合的投资者;将发现在一个仪表板中整合和定制所有资产持有非常方便。
为什么我在谷歌表格上的价格有限?
您可能会受到Google表格的价格限制;依赖于共享主机,其中一个谷歌服务器托管多个工作表。在同一服务器上发出请求的用户每分钟共享相同的API调用限制。这解释了为什么您可能会达到速率限制或遇到“#ERROR”;即使您只进行了几个API调用或导入了小范围的数据。
如果您是现有订阅者,并且拥有API密钥,请使用专业API根URL(https://pro-api.coingecko.com/api/v3/) 并在最后包含您的API密钥。URL结构将显示如下:
=导入json(“https://pro-api.coingecko.com/api/v3/硬币/市场?vs_currency=美元;订单=market_cap_desc&;每页=250&;第1页;火花线=真;价格变动百分比=1h%2C24h%2C7d&;locale=en&;精度=3&;x_cg_pi_key=YOUR_API_键“,”/name,/current_price,/market_cap,/price_change,/total_volume,/high_24h,/low_24h“,”no截断“,doNotDelete$A 1美元)
对于高级交易员:有用的CoinGecko API端点
以下是一些有用的API端点,高级交易员可能会发现这些端点特别有用:
- /硬币/钱包_用户-根据特定的时间框架,获得价格损益最大的前30种硬币
- /全球/市场图表-从现在起按天数获取历史全球市值和交易量数据
- /nfts/市场–跟踪NFT底价、市值和交易量
如果你是一名高级交易员,想要访问更全面的数据、历史价格和绕过利率限制,你可能想考虑订阅分析师API计划.
下载免费模板;⬇️
;
学分和;致谢
免责声明:文章中的所有内容仅代表作者的观点,与本平台无关。用户不应以本文作为投资决策的参考。
你也可能喜欢
比特币和以太坊ETF日流入总额超过10亿美元,BTC重新巩固至10万美元以上
简要概述 美国的现货比特币和以太坊ETF在周一共吸引了11亿美元的净流入。这一大规模资金流入帮助比特币在两周多以来首次回升至10万美元以上。
ALCHUSDT 现已上线合约交易和交易BOT
SWARMSUSDT 现已上线合约交易和交易BOT
Bitget 现货交易BOT新增2个交易对的公告