Oil prices react within seconds of Trump’s oil posts.
Oil prices moved 2× more around Trump’s oil posts than at the same time a week earlier. Half of Iran posts had moved oil more than 0.1% after 5 seconds.
WTI price data Dukascopy.
Volatility a week earlier 0.051, and when Trump posts 0.104.
30-second volatility (%)
A week earlier0.051
When Trump posts0.104
00.040.080.12
For 179 oil posts between 19 September 2025 and 24 September 2026, median WTI volatility over the next 30 seconds was 0.104%. That was about twice the 0.051% measured at the same time of day one or two weeks earlier. is the WTI bid seconds after the post,
A model better than guessing
Machine learning predicted whether oil prices would rise or fall over the next 30 seconds slightly better than guessing.
GPT-6 Luna identifies details in your text for the prediction model.
Try the model with this post, or write your own.
Time is key
Most of the edge is gone after 2–3 seconds.
I measured price changes over 30‑second windows beginning 0, 1, 2 or 3 seconds after each post. The later the window started, the lower the model’s prediction score.
Input
Target
X
Y
06The ML modelscikit-learnHistGradientBoostinglearning_rate 0.03max_iter 100max_depth 2max_leaf_nodes 8min_samples_leaf 10l2_regularization 1.0class_weight balanced
07Results by delayDelayF1 scoreGuessing0 s0.4400.301 s0.4010.302 s0.3550.303 s0.3280.30Each row measures a full 30‑second price change, starting at the delay shown. The score averages F1 for up and down predictions. Randomly choosing up, flat or down with equal probability scores about 0.30.
01Trump postsI collected his Truth Social feed from the trumpstruth.org archive, including original posts, reposts and videos.
02Keep his own posts4,138postsEach dot represents one of the 3,861 posts with GPT labels. Green dots mark oil-related posts.OpenAI GPT-6 Sol extracts 9 features from each post.
03Oil-related365postsWe filter the posts, keeping only those about oil.The prediction study had usable WTI prices for 266 posts.
04WTI pricesRetrieving WTI prices from Dukascopy.
05Define predictiontargetI labelled WTI’s change over 30 seconds as up above +0.075%, down below −0.075%, and flat otherwise.
Model input features
GPT-6 Sol labels each post. Fixed rules turn the labels into these 17 numbers, which the model reads.
Directionfrom fixed rules
Rules suggest higher pricesis_up0 · 1
Rules suggest lower pricesis_down0 · 1
The postfrom GPT
About IranHormuz includediran_sign−1 · +1
About anyone elseother_sign−1 · +1
Directly about oilprices, supply, shipping, OPECis_direct−1 · +1
The US actstakes, orders, threatens or pauses the stepis_us_direct0 · 1
Statusfrom GPT
Proposed or threatenedplans, threats, offersstatus_proposed_or_threatened0 · 1
Ordered or under wayagreed, ordered or donestatus_ordered_or_implementation_reported0 · 1
Called off or pausedstatus_withdrawn_or_suspended0 · 1
Each row measures a full 30‑second price change, starting at the delay shown. The score averages F1 for up and down predictions. Randomly choosing up, flat or down with equal probability scores about 0.30.
1
Trump posts
8,259
I collected his Truth Social feed from the trumpstruth.org archive, including original posts, reposts and videos.
2
Keep his own posts
4,138
4,138 he wrote himself; 3,861 of them have GPT labels. OpenAI GPT-6 Sol reads each one and extracts 9 features.
3
Oil-related
365
Filtered by the features: 191 directly about oil, 174 indirectly.
4
WTI prices
The WTI bid from Dukascopy, down to the tick.
5 Y
Define prediction target
I labelled WTI’s change over 30 seconds as up above +0.075%, down below −0.075%, and flat otherwise.
The sample is small and the testing period covers less than a year. Most events are tied to the Iran war, which limits how confidently these results can be applied to other events or market conditions.
02
Live trading remains untested
Using Claude agents, I simulated trading on the model’s calls: the historical returns were roughly zero after transaction costs. Live trading performance remains untested, including whether trades could be executed quickly enough and at the prices assumed in the simulation.
03
Broker CFD quotes rather than exchange prices
I used prices from Dukascopy, a broker. They may differ from exchange prices and don’t tell us exactly what real trades would cost.
04
No long-term predictive signal
The model did better than guessing only for the 30 seconds after a post, and most of the edge is gone after 2–3 seconds. In earlier tests with Claude agents, it showed no clear advantage over one or five days.
Summary
I studied whether Trump’s oil-related Truth Social posts could help predict oil prices.
Prices moved 2× more around his oil posts than at the same time a week earlier, and a model predicted the next 30‑second price direction slightly better than guessing. Its advantage weakened when price measurement started a few seconds later. In a trading simulation run with Claude agents, historical returns were roughly zero after costs, and live trading remains untested. The small sample, mostly tied to the Iran war, means more testing is needed.
— Majd Jamal
Example of Trump posts
Eight of the 8,259 items collected from his Truth Social feed, as they were posted.
1 / 8
Donald J. Trump@realDonaldTrump ·
Congratulations to America First Patriot, Jerry Kassar, who I very strongly supported, on his unanimous Re-Election as Chairman of the Conservative Party of New York State. Jerry is MAGA all the way, and has dedicated his life to the Conservative Party, and the ONCE GREAT STATE OF NEW YORK (IT CAN BE GREAT AGAIN!). I know Jerry will continue to do a fantastic job, and secure many Victories for New York Conservatives and Republicans in the 2026 Midterm Elections, and beyond. THANK YOU NEW YORK — MAGA2026! President DONALD J. TRUMP
Donald J. Trump@realDonaldTrump ·
Kharg Island being blown to smithereens!!! President DJT
Video
Oil-related
Donald J. Trump@realDonaldTrump ·
Israel and Iran must immediately stop “shooting.” President DONALD J. TRUMP
Oil-related
Donald J. Trump@realDonaldTrump ·
For Iran, the Clock is Ticking, and they better get moving, FAST, or there won’t be anything left of them. TIME IS OF THE ESSENCE! President DJT
Oil-related
Donald J. Trump@realDonaldTrump ·
IRAN HAS JUST ANNOUNCED THAT THE STRAIT OF IRAN IS FULLY OPEN AND READY FOR FULL PASSAGE. THANK YOU!
Oil-related
Donald J. Trump@realDonaldTrump ·
The United States to Blockade Ships Entering or Exiting Iranian Ports on April 13 at 10:00 A.M. ET. Thank you for your attention to this matter! President DJT
Oil-related
Donald J. Trump@realDonaldTrump ·
Such a shining light. Rest in peace, Sheridan, you will be greatly missed!!! President DONALD J. TRUMP
@DanScavino
Rest in Peace, Sheridan Gorman.
Your voice will be heard, and you will never be forgotten. The President and The White House stand with the Gorman Family.
#JusticeforSheridan
3/28/26—Yorktown Heights, New York…
https://www.instagram.com/reel/DWdDwgvjmvF/?igsh=MXFtaWszYnk3MnN6aw==
WTI crude in US dollars, the Dukascopy bid: a year, the minute round his post of 18 May 2026, 19:01:25 UTC, and the 30 seconds after it, second by second.
Each trading day’s last bid, 18 Sep 2025 to 24 Sep 2026: 303 days.
How one post becomes one row of X, the 17 numbers the model reads.
1 / 10
1Truth post
Donald J. Trump18 May 2026 · 3:01 PM ET
I have been asked by the Emir of Qatar, Tamim bin Hamad Al Thani, the Crown Prince of Saudi Arabia, Mohammed bin Salman Al Saud, and the President of the United Arab Emirates, Mohamed bin Zayed Al Nahyan, to hold off on our planned Military attack of the Islamic Republic of Iran, which was scheduled for tomorrow, in that serious negotiations are now taking place, and that, in their opinion, as Great Leaders and Allies, a Deal will be made, which will be very acceptable to the United States of America, as well as all Countries in the Middle East, and beyond. This Deal will include, importantly, NO NUCLEAR WEAPONS FOR IRAN! Based on my respect for the above mentioned Leaders, I have instructed Secretary of War, Pete Hegseth, The Chairman of The Joint Chiefs of Staff, General Daniel Caine, and The United States Military, that we will NOT be doing the scheduled attack of Iran tomorrow, but have further instructed them to be prepared to go forward with a full, large scale assault of Iran, on a moment’s notice, in the event that an acceptable Deal is not reached. Thank you for your attention to this matter! President DONALD J. TRUMP
Today, the United States of America, in coordination with the Interim Authorities of Venezuela, seized an oil tanker which departed Venezuela without our approval. This tanker is now on its way back to Venezuela, and the oil will be sold through the GREAT Energy Deal, which we have created for such sales. Thank you for your attention to this matter!
Effective immediately, any Country doing business with the Islamic Republic of Iran will pay a Tariff of 25% on any and all business being done with the United States of America. This Order is final and conclusive. Thank you for your attention to this matter!
PRESIDENT DONALD J. TRUMP
It is my Great Honor to have just signed, from the Oval Office, a Global 10% Tariff on all Countries, which will be effective almost immediately. Thank you for your attention to this matter! PRESIDENT DONALD J. TRUMP
If Iran doesn’t FULLY OPEN, WITHOUT THREAT, the Strait of Hormuz, within 48 HOURS from this exact point in time, the United States of America will hit and obliterate their various POWER PLANTS, STARTING WITH THE BIGGEST ONE FIRST! Thank you for your attention to this matter. President DONALD J. TRUMP
As per Iranian Government request, please let this statement serve to represent that I am pausing the period of Energy Plant destruction by 10 Days to Monday, April 6, 2026, at 8 P.M., Eastern Time. Talks are ongoing and, despite erroneous statements to the contrary by the Fake News Media, and others, they are going very well. Thank you for your attention to this matter! President DONALD J. TRUMP
One of the things I am going to do with the Venezuelan Oil is fill up the Strategic National Reserves which, because of Sleepy Joe Biden, has been virtually emptied. The “topping out” process will begin very shortly, and is a Gift from Venezuela to the People of the United States. Thank you! President DONALD J. TRUMP
Ukraine has agreed not to hit Russian Energy targets. Russia has agreed to do, likewise! The World’s Diesel price rise is mostly caused by the Russia/Ukraine War, not Iran. President DJT
Python, scikit-learn and pandas: the model, the data reader and the study.
src/model.py · GitHub main @ 7ab618534 lines
1""" The classifier (a small gradient-boosted tree model with fixed settings)2and the walk-forward settings.3"""45__author__='Majd Jamal'67from sklearn.ensemble import HistGradientBoostingClassifier
8910MIN_TRAIN =30# walk forward: posts needed before the first test month11FIRST_TEST_MONTH ='2026-02'# walk forward: months from here are tested; earlier posts only train121314PARAMS ={15'learning_rate':0.03,# small steps: each tree corrects the previous ones only a little16'max_depth':2,# shallow trees: at most two questions per tree17'max_leaf_nodes':8,18'min_samples_leaf':10,# every answer must be backed by at least 10 posts19'l2_regularization':1.0,# shrinks extreme leaf values20'max_iter':100,# number of trees21'class_weight':'balanced',# up, flat and down count equally, even if one is more common22'random_state':0,23}2425defbuild_model():26""" Returns an unfitted classifier for the per-post target: the WTI move in the 30 seconds after the post, up (1), flat (0) or down (-1).27 The settings are fixed in advance, not tuned.28 """29return HistGradientBoostingClassifier(**PARAMS)303132deftrain(model, X_train, y_train):33 model = model.fit(X_train, y_train)34return model
src/data_reader.py · GitHub main @ 7ab618544 lines
1""" Reads Trump's Truth Social posts (data.json) and the WTI prices (data/oil_indices).2"""34__author__='Majd Jamal'56import pandas as pd
78TRUTHS ='data/posts.json'# the posts without their text: id, link, time and author91011WTI_RESOLUTION ={'1s':'data/oil_indices/wti_1s.csv',12'tick':'data/oil_indices/wti_ticks.csv',13'posts':'data/oil_indices/wti_post_prices.csv'}# the bid 0-5 s and 30-35 s after each oil post (published)1415defread_trumps_posts():16""" Loads data.json and returns only the posts written by Trump himself.17 """18 df = pd.read_json(TRUTHS)1920 X =['id','archive_id','author_name','published_at_utc','published_at_et','kind']2122 df = df[df['is_written_by_trump']==True][X]23 df['published_at_utc']= pd.to_datetime(df['published_at_utc'])2425return df
2627defread_wti(res ='tick'):28"""29 :param res: Input resolution for the data30 """3132 wti = WTI_RESOLUTION[res]33 wti = pd.read_csv(wti)3435 wti['time_utc']= pd.to_datetime(wti.time_utc)36 wti = wti.set_index(wti.time_utc)37 wti = wti.drop(columns =['time_utc'])3839return wti
404142if__name__=="__main__":4344 oil_prices = read_wti(res ='1d')
src/analyze.py · GitHub main @ 7ab618586 lines
1""" Runs the study: labels each oil post with the WTI move 30 s after it (up, no move, down),2tests the model month by month (walk forward) and prints the macro F1.34Run from the project root: python3 src/analyze.py5"""67__author__='Majd Jamal'8910import os
1112import numpy as np
13import pandas as pd
14from sklearn.metrics import f1_score
15from tqdm import tqdm
1617from data_reader import read_trumps_posts, read_wti
18from data_pre_processing import pre_process, make_labels, intersect
19from model import build_model, MIN_TRAIN, FIRST_TEST_MONTH
2021FEATURES ='data/features.json'2223resolution ='posts'2425defread_features():2627ifnot os.path.exists(FEATURES):28raise FileNotFoundError('Features not computed yet! Run a batch with: python3 src/feature_engineering.py')2930 ft = pd.read_json(FEATURES)31 truths = read_trumps_posts()3233 ft = ft.merge(truths, on='id')34 ft = ft.set_index('published_at_utc')3536return ft
3738defread_price():3940return read_wti(resolution)414243defwalk_forward(X, Y):444546 preds = pd.Series(np.nan, index=X.index)4748 months = X.index.strftime('%Y-%m')4950for month in tqdm(sorted(set(months))):5152 hgb = build_model()5354 X_train = X[months < month]55 X_test = X[months == month]5657 Y_train = Y[months < month]5859if month < FIRST_TEST_MONTH orlen(Y_train)< MIN_TRAIN or Y_train.nunique()<2:60continue6162 hgb.fit(X_train, Y_train)6364 preds[months == month]= hgb.predict(X_test)6566return preds
6768if__name__=='__main__':6970 features = read_features()71 features = features[features['oil_relevance']!='none']# only posts about oil72 X = pre_process(features)737475 prices = read_price()76 Y = make_labels(prices, features, delay ='0s', window='30s')['sign']7778 keep = Y.notna().values # only posts with a price before and after79 X, Y = X[keep], Y[keep]8081print(X.shape)82 preds = walk_forward(X, Y)8384 tested = preds.notna()85print(tested.shape)86print(f1_score(Y[tested], preds[tested], labels=[-1,1], average='macro'))