Alpaca and Snap Inc. have recently partnered up and we’re excited to share that we integrate with the Snap Lens Studio AR creation tool. We are one of the few companies to offer real-time data in Lens Studio, and the timing couldn't be better. With the gaining popularity of finance-focused influencers and consistent participation in the U.S. stock market [1], this presents a unique opportunity for creators to share finance-related content and reach a wider audience.
The Alpaca stock market data endpoints currently available in Lens Studio are Trades, Quotes, Bars, and Snapshot. For more information on how these endpoints are used and what they are, read this article. To show how creators can start having fun with this new API, we’ve created a Snap Lens that gets the high price of a stock and generates realistic AR dollar bills proportional to the value of the stock. The stock chosen for this lens is Telsa Inc. (NASDAQ: TSLA) because its stock price has seen a wide range in the last five years. [2]
The following sections walk you through some of the high-level details on how the Snap Lens is made, but if you just want to start using the end product right away, skip to the last section called “How to access and use the final lens.”
How does our lens request and display market data?
Taking baby steps, the first thing we need to do here is to find out how to use this API. Luckily, Snap has included a template project in Lens Studio that implements every function you’ll need to get market data. You can find that on the start-up screen of Lens Studio, or by searching for “Stock Market API” on start-up. For details on exactly how this template works, check out Snap’s user guide.
Opening it up and checking out the scripts, we’ll find all the functions by looking inside the “Scripts” folder and locating the “AlpacaAPIWrapper” file. You’ll see functions for getTrades, handleAPIResponse, getBars, and more. In our case, because we want to grab the high price on a specific date, we’ll be copying over the getBars function. In addition, copy over the handleAPIResponse function so we can make safe API requests. With these functions in hand, create a new project for your lens and paste them into a new script.
function handleAPIResponse(response, cb) {
if (response.statusCode !== 1) {
print("ERROR: The API call did not succeed!. Please check your request");
cb(true);
} else {
try {
var parsedBody = JSON.parse(response.body);
if (cb) {
cb(false, parsedBody);
}
} catch (e) {
print("ERROR: Failed to parse response");
if (cb) {
cb(true);
}
}
}
}
var getBars = function(symbol, start, end, limit, page_token, timeframe, adjustment, cb) {
var request = global.RemoteApiRequest.create();
request.endpoint = "get_bars";
request.parameters = {"symbol": symbol, "start": start, "end": end, "limit": limit, "page_token": page_token, "timeframe": timeframe, "adjustment": adjustment};
script.rsm.performApiRequest(request, function(response) {
if (cb) {
handleAPIResponse(response, cb);
}
});
};
Together, this script will request Bar data for a given stock and handle the response object. Now what we want to do is get the high price on a given day and display it in a text object. Therefore, after creating a text object, we’ll code up the first draft of our text updating function. Given the symbol to query for, this function will create Date objects representing now and a week ago to grab the bars. Then if the API returns with no problems, we update the text object with the high price of the most recent bar to two decimal places.
var symbol = "TSLA"
// This function will update the textbox according to $TLSA's high at the given date
function updateTeslaPrice(sliderDate) {
// Alpaca API requires calls to be 15 minutes ago or more
var now = new Date();
now = new Date(now.getTime() - 30*60*1000);
var sevenDaysAgo = 60*60*24*7*1000;
var oneWeekAgo = new Date(now.getTime() - sevenDaysAgo);
getBars(symbol, oneWeekAgo.toISOString(), now.toISOString(), undefined, undefined, "1Day", undefined, function(err, body) {
if (err) {
print("ERROR: API did not return correctly");
} else {
barsObject = JSON.stringify(body.bars[0]);
highPrice = body.bars[0].h.toFixed(2);
script.t.text = "$" + String(highPrice);
}
});
}
This should work! But it’s static and will only display the high price of the first bar in the response.
So how can we create an interface to dynamically update the stock price for different days?
The most intuitive way to allow users to select from a smooth range of values is by using a slider. Lens Studio once again has a prebuilt code template for us to take from! Navigating to their user interface guide, Snap has made some UI objects available for download and import by clicking the “Download the UI system” button. Following the instructions here to import the UI objects, you’ll end up with many extra objects. We’ll modify their “UI Color Picker” slider, so disable and delete everything that isn’t related to this object. After disabling the extraneous features, we’ll move the slider into a more sensible position.
Looks good! Now we have to configure the slider value such that we can control a date. The slider controls a floating-point number ranging from 0 to 1. Given that in this lens we’re constraining our date range to an interval of 5 years ago to 15 minutes ago, we can use some basic algebra to create a linear equation that maps our float to a date.
// This function takes the slider value and returns a date offset
// ranging from five years ago to fifteen minutes ago.
function sliderToDate(sliderVal) {
const fiveYearsAgo = 60*60*24*365*5*1000;
const fifteenMinsAgo = 15*60*1000;
offset = sliderVal * (fiveYearsAgo-fifteenMinsAgo) + fifteenMinsAgo
return offset
}
Now, putting this all together in our text updating function, we get our second draft. In addition to modifying our text updater, we’ll take some lines from the UI tutorial that adds a callback function to the slider.
var symbol = "TSLA"
// This function will update the textbox according to the symbol's high at the given date
function updateTeslaPrice(sliderVal) {
var offset = sliderToDate(sliderVal)
var dateOfStockPrice = new Date();
dateOfStockPrice = new Date(dateOfStockPrice.getTime() - offset);
var oneDay = 60*60*24*1*1000;
var dateBefore = new Date(dateOfStockPrice.getTime() - oneDay*2);
// Bars must have a start and end in the query, so we use one day as an interval.
getBars(symbol, dateBefore.toISOString(), dateOfStockPrice.toISOString(), limit=50, undefined, "1Hour", "all", function(err, body) {
if (err) {
print("ERROR: API did not return correctly");
} else {
last_idx = body.bars.length - 1;
barsObject = JSON.stringify(body.bars[last_idx]);
highPrice = body.bars[last_idx].h.toFixed(2);
//updates values for instantiating
global.number = highPrice;
script.t.text = "$TSLA = $" + String(highPrice);
script.tDate.text = String(dateOfStockPrice).slice(4, -24);
}
global.updated = true;
});
}
script.colorPickerScript.api.addCallback("onSliderValueChanged", updateTeslaPrice);
updateTeslaPrice(script.initialValue);
script.colorPickerScript.api.setSliderValue(script.initialValue);
Now the slider is successfully configured and will dynamically update the text object according to the position of the color picker.
Using the current stock price to instantiate money and adding the finishing touches
Before we can start instantiating cash, we’ll need to import the assets and create objects. The ones used for this snap lens can be found in our GitHub repo. As is common in the rest of this app, to define the physics and behavior of our objects we’ll be taking from Snap’s templates. Navigating to the start-up page of Lens Studio, click on the Physics template. From here open up the scripts folder and copy the “Behavior” file. Following Snap’s user guide, the behavior of our objects will be taken care of.
There are two last scripts we’ll need to write for our objects: one for instantiation and one for deletion. These two scripts will trigger on the events “touch ended” and “touch started” respectively. To determine the number of bills to create, we’ll write a simple routine that separates the stock price into two components: the amount representable by hundreds and everything leftover representable in whole dollars. After calculating these two quantities, we simply write loops to instantiate the appropriate models according to the quantities. Deletion is simply a one-liner that tells the script to grab the scene objects and destroy (delete) them.
if(global.number){
const numberOfShares = 1;
var valueToInstantiate = global.number * numberOfShares;
var numberOfOnes = valueToInstantiate % 100;
var numberOfHundreds = (valueToInstantiate - numberOfOnes) / 100;
for (var i=0; i<numberOfOnes; i++) {
script.one.instantiate(script.getSceneObject());
}
for (var j=0; j<numberOfHundreds; j++) {
script.hundred.instantiate(script.getSceneObject());
}
}
script.getSceneObject().destroy();
Lastly, import the last assets to add styling to the slider and text box and we’re finished!
How to use access and use the final lens
You can access the lens by scanning the Snapcode found here[LINK] or by visiting the GitHub repo. Once the lens has loaded into your app, you can use the slider to select a date on which to show a stock’s price. Upon letting go of the slider, AR money will generate proportional to the price you’ll see on screen.
Conclusion
The end result is a fun, interactive lens that helps to show how stocks can grow over time! This lens can be customized to work for any stocks traded on American exchanges, so feel free to build upon the repo. This lens used just one endpoint of many and we hope it inspires creators to explore what’s possible in this fast-growing space.
References
[1] Lydia Saad and Jeffrey M. Jones, “What percentage of Americans owns stock?,” Gallup.com, 20-Nov-2021. [Online]. Available: https://news.gallup.com/poll/266807/percentage-americans-owns-stock.aspx. [Accessed: 26-Jan-2022].
[2] “Tesla, Inc. (TSLA) Stock Historical Prices & Data,” Yahoo! Finance, 26-Jan-2022. [Online]. Available: https://finance.yahoo.com/quote/TSLA/history/. [Accessed: 26-Jan-2022].
Please note that this article is for educational and informational purposes only. All images and mathematical equations are for illustrative purposes only. Alpaca does not recommend any specific securities or investment strategies.
All investments involve risk and the past performance of a security, or financial product does not guarantee future results or returns. Keep in mind that while diversification may help spread risk it does not assure a profit, or protect against loss, in a down market. There is always the potential of losing money when you invest in securities, or other financial products. Investors should consider their investment objectives and risks carefully before investing.
Alpaca does not prepare, edit, or endorse Third Party Content. Alpaca does not guarantee the accuracy, timeliness, completeness or usefulness of Third Party Content, and is not responsible or liable for any content, advertising, products, or other materials on or available from third party sites.
Brokerage services are provided by Alpaca Securities LLC ("Alpaca"), member FINRA/SIPC, a wholly-owned subsidiary of AlpacaDB, Inc. Technology and services are offered by AlpacaDB, Inc.
This is not an offer, solicitation of an offer, or advice to buy or sell securities, or open a brokerage account in any jurisdiction where Alpaca is not registered (Alpaca is registered only in the United States).