Self Hosted AI Experiments
Seeing What You Can Do For Free
The past week has been a slow grind watching the needle on the Global Gas Tank move closer and closer to empty, and waiting for it to hit the magic moment when all of our Energy/Fertilizer/Refinery/LNG positions wake up. This feels a lot like 2024-2025 when the Silver Market ground higher slowly on high volatility, then exploded. Managing the grind is a big factor in successful trading. During the wait, I did some experiments using self-hosted AI to see what it could do on a quad core machine with 16 gigabytes of RAM and no GPU.
The AI Experiments give some insight into if and/or when an AI Bust arrives. If users can do powerful things offline, on cheap hardware, then the business case for buying compute time (aka ‘Tokens’) from Anthropic or OpenAI goes way down. If your product costs hundreds or thousands of dollars per user per month, it becomes hard to compete with free. Needless to say, if Anthropic or OpenAI goes down, singly or in combination, this is very, very bad news for their big shareholders (Microsoft) or suppliers (Nvidia, Oracle).
To get started, I needed a small project to try out. I decided to do a Substack Finance Summarizer that would pull my five favorite Substack feeds, and write a summary of each one.
To get started, I submitted a Google Search with the phrase:
how to summarize most recent articles on substack in c++ using deepseek api running locally
I originally did a search query without specifying C++, and Google Gemini provided some Python Code which did not run because of library incompatibilities. After an hour or three of library installs and uninstalls I decided to take a gamble and see what would happen if I specified C++ as the programming language.
This search query produced a Google Gemini AI response with some not bad looking C++ code to do what I wanted. However, it used a JSON parser that I hadn’t used before and I hate having a bunch of different libraries around that all do the same thing. So I added a qualifier to use the picojson libary that I used in previous projects.
how to summarize most recent articles on substack in c++ using deepseek api and the picojson library running locally
This produced some decent C++ that looked good. I replace the boilerplate code for the Substack URLs with real Substack Urls instead. Surprisingly, the code compiled with no errors or warnings and ran successfully once I figured out the correct formatting of the Substack RSS URL, which was not exactly clear in the Substack Documentation.
Here are the feeds I selected:
“https://nuclearoptiontrading.substack.com/feed”,
“https://jensendavid.substack.com/feed”,
“https://defytheodds88.substack.com/feed”,
“https://hfir.substack.com/feed”,
“https://porterstansberry.substack.com/feed”
The C++ code that Google Gemini generated is at the end of this post.
Here is how to put everything together to run the code. This example uses the Ubuntu Linux Terminal, however you can use the Linux Subsystem on Windows or the Terminal Window in MacOS to get exactly the same behavior.
Install ollama open source AI model harness:
curl -fsSL https://ollama.com/install.sh | sh
This is an install script, you only need to run this once.
Run ollama using the DeepSeek model optimized for low quality hardware:
ollama run deepseek-r1:1.5b
Copy the C++ code that Google Gemini wrote into a file named summarize.cpp and save it.
Compile the C++ code like this:
g++ summarize.cpp pugixml.cpp -lcurl -o summarize
You can run the program like this:
./summarize
Here is the output from the inference run, which took a while on my GPU-free hardware:
================= DeepSeek Summary =================
<think>
Okay, I need to summarize the given newsletter updates into a concise and engaging weekly digest. Let me read through each point one by one.
First, “Our Ideas Are Going Mainstream: But Are Not Priced in ... Yet.” This seems to be about expanding their focus but hasn’t been sold yet. I should mention that their ideas are moving fast but not available immediately.
Next, the new Morgenthau Plan mentions an 80-year delay. I need to highlight that this plan is being delayed further, which could slow down their development or investment.
Silly Season/Smart Season update: Position Update. This sounds like an announcement about a sector change in their management team. Maybe they’re shifting focus to a new area, so I’ll note that.
Speaking of gold and silver, the idea that their rising prices are warning of currency issues and inflation. They have historically warned against this, which could push interest up. That’s an important point because it affects their trading strategies.
Moving on to oil and lubricant shortages in the US from the Persian Gulf disruption. They’ve reported a 44% loss of base oil supply. This seems like a critical issue affecting production and could impact their revenue negatively. It’s worth mentioning that this situation is causing uncertainty.
The video about citizen silver stopping the digital slave system suggests public concern about controlled fiat currencies being used for exchange and savings. This could affect their financial management practices, so I should note that as well.
When they meet on the bond market with physical reality—maybe a regulatory or policy change? It’s good to mention that this is happening right on schedule, so it can’t be too far off.
Intermarket Big Picture: Stagflation in multiple markets. They’re hitting several hard truths at once. This could influence their strategies and risk assessment, so I should explain that briefly.
Mapping the Iran War damage—maybe they’re assessing the impact of the conflict on their operations or policies. The warranty expired might mean something critical is being addressed, which ties into their current issues.
The endgame issue #79, volume 3: That’s a specific problem, but it’s near the end of the week, so maybe it’s a last push or an upcoming event. It could signal important changes they’re preparing for, so I’ll note that too.
Finally, the second shock from Hormuz—it must be an economic indicator or event related to that currency. Their returns are up 2134%, which is a significant jump. That should draw attention to it as well.
I need to condense all these points into one digest without missing any key takeaways. I’ll structure each main point, maybe using bullet points for clarity. I also want to make sure the language stays engaging and concise, avoiding too much technical jargon unless necessary.
</think>
**Weekly Digest: Exploring Current Events & Trends**
1. **Expanding Focus Fast:** Our Ideas are trending but not yet priced in—highlighting their fast expansion without immediate availability.
2. **Morgenthau Plan Delayed:** An 80-year delay expected, affecting their development or investment timelines.
3. **Silly/Smart Season Update:** Management shifts focus to a new sector, potentially altering their strategy and team dynamics.
4. **Currencies’ warning of issues:** Rising prices in gold and silver are signaling currency devaluation and inflation concerns, impacting trading strategies.
5. **OIL and LUBRIDANT DISPLACMENT:** US supply loss from the Persian Gulf has reduced production, causing market uncertainty with a 44% drop in base oil supply.
6. **Digital slave system concern:** Public scrutiny on centralised fiat currencies being used for exchange and savings, affecting financial management.
7. **Bond Market Meet:** Simultaneous impact of multiple markets facing hard truths—stagnant stagflation issues across several sectors.
8. ** Iran Conflict Impact:** Assessment of Iran’s economic impact, with a noted warranty expired—indicating critical attention to its effects.
9. **Endgame Issue #79:** Likely near the end of the week, marking an upcoming challenge or change—preliminary but significant.
10. **Hormuz shock News:** A second significant economic indicator, with returns up 2134%, highlighting a sharp development point.
This digest captures key developments across various sectors, from market trends to policy shifts, ensuring you stay informed on the latest events.
====================================================
END OF DEEPSEEK OUTPUT
There are a couple of lessons to learn from this experiment.
First is that Google’s Gemini had no problems at all implementing a small, pain in the neck C++ project involving proprietary APIs from Substack and DeepSeek. This saves lots of time going up the learning curve in proprietary APIs — a big time sink in most small to mid-size projects.
Second, it appears that the AI Summary is, shall we say, a bit behind the curve in interpreting nuances in the English Language. DeepSeek did a good job summarizing the more literal Substack posts, for example
Rising prices in gold and silver are signaling currency devaluation and inflation concerns, impacting trading strategies.
Moving to the less literal posts, the results were occasionally hilarious, most notably with my recent post on the de-industrialization of Germany:
**Morgenthau Plan Delayed:** An 80-year delay expected, affecting their development or investment timelines.
As an experiment, I tried running a search query in Google AI Mode to see if Gemini was just as funny, here is the result:
A few recent Substack posts compared recent DeepSeek/qwen models vs. Open AI and Claude Code, I’m not doing this here because I learned the hard way that if there is no Free Software Solution available, it is usually best to do nothing and not to yield to temptation by using commercial closed source software offerings.
The key takeaway from this experiment is that offline AI works, and it poses a significant threat to high cost offerings from firms that are currently incinerating hundreds of billions of dollars to replicate what you can do at home, for free.
As usual, timing is everything in options trading, so we’ll be looking at potential triggers for a spectacular bust in everything AI related. A lot of mainstream news articles on Self Hosted AI might be the ticket to get things rolling.
Disclaimer: All Content on the Nuclear Option Substack is for Information and Educational Purposes Only. Before trading, consult with your Professional Financial Advisor and read the Booklet Characteristics and Risks of Standardized Options Contracts published by the Options Clearing Corporation.
APPENDIX A:
Here is the code in the example above:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <curl/curl.h>
#include “pugixml.hpp”
#include “picojson.h”
// Callback for libcurl to write HTTP response data to a string
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
// Function to fetch content via libcurl (handles both RSS/Atom feeds and API requests)
std::string fetchUrlContent(const std::string& url) {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_USERAGENT, “C++ Substack Summarizer/1.0”);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(res != CURLE_OK) {
std::cerr << “curl_easy_perform failed: “ << curl_easy_strerror(res) << std::endl;
return “”;
}
}
return readBuffer;
}
// Function to parse Substack RSS/Atom feed and concatenate recent articles
std::vector<std::string> extractArticlesFromFeed(const std::string& feedXmlStr) {
std::vector<std::string> articles;
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_string(feedXmlStr.c_str());
if (!result) return articles;
// Search for standard RSS items
for (pugi::xml_node item : doc.child(”rss”).child(”channel”).children(”item”)) {
std::string title = item.child_value(”title”);
std::string description = item.child_value(”description”);
articles.push_back(title + “: “ + description);
if (articles.size() >= 3) break; // Limit to 3 articles per feed for conciseness
}
// Fallback: Search for Atom entries
if (articles.empty()) {
for (pugi::xml_node entry : doc.child(”feed”).children(”entry”)) {
std::string title = entry.child_value(”title”);
std::string summary = entry.child_value(”summary”);
articles.push_back(title + “: “ + summary);
if (articles.size() >= 3) break;
}
}
return articles;
}
// Function to send concatenated content to local DeepSeek and get summary
std::string getLocalDeepSeekSummary(const std::string& combinedContent) {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if(curl) {
// Construct the JSON payload for Ollama/DeepSeek
std::cout << “--A--” << std::endl;
picojson::object jsonPayload;
jsonPayload[”model”] = picojson::value(”deepseek-r1:1.5b”); // Change to your specific model if needed
jsonPayload[”prompt”] = picojson::value(”Summarize the following recent updates from Substack newsletters into a concise, engaging weekly digest:\n\n” + combinedContent);
jsonPayload[”stream”] = picojson::value(false);
picojson::value root(jsonPayload);
std::string payloadStr = root.serialize();
std::cout << “--B--” << std::endl;
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, “Content-Type: application/json”);
curl_easy_setopt(curl, CURLOPT_URL, “http://localhost:11434/api/generate”);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payloadStr.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
std::cout << “--C--” << std::endl;
res = curl_easy_perform(curl);
std::cout << “--D--” << std::endl;
curl_slist_free_all(headers);
std::cout << “--E--” << std::endl;
curl_easy_cleanup(curl);
std::cout << “--F--” << std::endl;
std::cout << “readbuffer is: “ << readBuffer << std::endl;
if(res == CURLE_OK) {
picojson::value v;
std::string err = picojson::parse(v, readBuffer);
std::cout << “--G--” << std::endl;
if (err.empty() && v.is<picojson::object>()) {
return v.get<picojson::object>()[”response”].get<std::string>();
}
std::cout << “--H--” << std::endl;
}
}
return “Error generating summary from local DeepSeek.”;
}
int main() {
// 1. Define your five Substack feeds
std::vector<std::string> feedUrls = {
“https://nuclearoptiontrading.substack.com/feed”,
“https://jensendavid.substack.com/feed”,
“https://defytheodds88.substack.com/feed”,
“https://hfir.substack.com/feed”,
“https://porterstansberry.substack.com/feed”
};
std::string combinedArticles = “”;
// 2. Fetch and parse each Substack feed
for (const std::string& feedUrl : feedUrls) {
std::cout << “Fetching: “ << feedUrl << std::endl;
std::string feedXml = fetchUrlContent(feedUrl);
if (!feedXml.empty()) {
std::vector<std::string> articles = extractArticlesFromFeed(feedXml);
for (const std::string& article : articles) {
combinedArticles += “- “ + article + “\n”;
}
}
}
if (combinedArticles.empty()) {
std::cerr << “No articles found to summarize.” << std::endl;
return 1;
}
// 3. Send to Local DeepSeek & Print Summary
std::cout << “\nSending content to local DeepSeek (this may take a few moments)...” << std::endl;
std::string summary = getLocalDeepSeekSummary(combinedArticles);
std::cout << “\n================= DeepSeek Summary =================” << std::endl;
std::cout << summary << std::endl;
std::cout << “====================================================” << std::endl;
return 0;
}
~



Like it. Think your onto something. Being a retired 35yr DSP researcher/programmer in communications its awesome to see people doing what was being done back in late 70s and 80s on PCs by individuals when big mainframes and super minis were the tools used and available only to a select few. Now with the big parallel processing farms used for AI I suspect that again there will be creative individuals who will make advances to bring localized processing with new HW and smaller open source models that won't require expensive subscriptions. It may already be happening but dont know scale.
This is so cool! Keep up!