You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
this is an example of how to integrate Mistral AI APIs with backtest framework .
Pay attention
The prompt is intentionally simple, as are the provided data. The idea is just to show how you can use Mistral AI and backtestJS together, so do not use this prompt in production.
Below, are all the necessary files, you can use the "quick-start" project as a quick base:
Create the simple.ts file and insert the content you find below.
Modify the code in main.ts as shown in the example below.
Add/modify your .env file as needed.
To activate your Mistral API Key, refer to Mistral AI
By running npm run dev, you will see something similar in the console:
Request on candle time 1724774399999
Last price: 55322.86
Result - decision: BUY
Result - confident: 8
Result - reason: The SMA (20) is above the SMA (50), indicating an upward trend. The recent price action has shown a general upward movement with some retracement, which is typical in a bullish trend. The volume has been relatively stable, indicating consistent buying pressure. The recent drop to 55322.86 could be a buying opportunity as it approaches the SMA (20).
TRACE: Real buy performed
Request on candle time 1724803199999
Last price: 53243.79
Result - decision: SELL
Result - confident: 8
Result - reason: The recent price trend shows a significant decline from 57273.94 to 53243.79 over the last 10 candles, indicating a bearish momentum. The SMA (20) is above the SMA (50), which suggests a short-term uptrend, but the recent drop below both SMAs indicates a potential trend reversal. The high volume on the last candle (126.17) supports a strong bearish move. The risk-reward ratio favors taking profits or closing a position to avoid further losses.
TRACE: Real sell performed
simple.ts
import{BTH,Candle}from'@backtest/framework'import*asindicatorfrom'technicalindicators'import{Mistral}from'@mistralai/mistralai'constapiKey=process.env['MISTRAL_API_KEY']if(!apiKey){thrownewError('missing MISTRAL_API_KEY environment variable')}constclient=newMistral({apiKey: apiKey})exportconstproperties={params: ['lowSMA','highSMA','percentFee','percentSlippage'],dynamicParams: false}exportasyncfunctionrunStrategy(bth: BTH){if(bth.tradingCandle){// Simple Moving AverageconstlowSMAInput=bth.params.lowSMA||20consthighSMAInput=bth.params.highSMA||50constcloses=awaitbth.getCandles('close',Math.max(lowSMAInput,highSMAInput),0)constlowSMAs=indicator.SMA.calculate({period: lowSMAInput,values: closes.slice(-lowSMAInput)})consthighSMAs=indicator.SMA.calculate({period: highSMAInput,values: closes.slice(-highSMAInput)})constlowSMA=lowSMAs[lowSMAs.length-1]consthighSMA=highSMAs[highSMAs.length-1]// Last N candlesconstlastCandles=awaitbth.getCandles('candle',10,0)constlastCandlesText: string[]=lastCandles.map((c: Candle)=>{return`- Timestamp: ${c.closeTime}, Close: ${c.close}, Volume: ${roundTo(c.volume,3)}; `})constprompt=`You are a highly experienced day and swing trader. Your task is to evaluate the provided data for ${bth.currentCandle.symbol} and respond with a structured plain TEXT object: { "decision": "BUY" | "SELL" | "OTHER", "reason": "[Optional explanation of key factors influencing the decision]", "confident": "[From 0 to 10, how much you feel confident on this decision]" } ### Evaluation Methodology: - Apply advanced mathematical models to calculate potential profits, factoring in fees (${bth.params.percentFee}%) and maximum slippage (${bth.params.percentSlippage}%). - Assess short-term and long-term trends using key technical indicators and charting tools. - Examine all data provided. - Evaluate risk-reward scenarios to ensure optimal decision-making. - Scientifically and mathematically calculate appropriate take-profit and stop-loss levels based on volatility, average true range (ATR), and historical price behavior. ### Data Provided: **Technical Indicators**: SMA (${lowSMAInput}): ${lowSMA} SMA (${highSMAInput}): ${highSMA} **Last ${lastCandlesText.length} OHLC Candles and Volumes**: ${lastCandlesText.join('\n')} ### Decision Rules: 1. If a position is open, decide whether to SELL based on profit potential. 2. If no position is open, decide whether to BUY based on market strength, trend continuation, or breakout potential. 3. If the data is inconclusive or signals are conflicting, respond with OTHER. 4. For every decision (BUY or SELL), calculate scientifically the "confident" score. **Respond with plain TEXT object as specified above and don't use MD syntax.**`letresponseMessage: string|undefinedletcount: number=0letresult: any=nullwhile(count<=2){try{if(count>0){console.log('Ok, wait a bit and retry..')awaitsleep(2000)}count++console.log(`\nRequest on candle time ${bth.currentCandle.closeTime}\nLast price: ${bth.currentCandle.close}`)constresponse=awaitclient.chat.complete({model: 'mistral-large-latest',messages: [{role: 'user',content: prompt}]})// ok, ok not so good to do but ..responseMessage=response?.choices ? response?.choices[0]?.message?.content?.toString() : ''result=responseMessage ? JSON.parse(responseMessage.replace(/`{3,}/g,'')) : {decision: 'OTHER'}awaitsleep(1000)count=100// just to exit}catch(err){console.log(err)console.log(responseMessage)}}if(!('decision'inresult)||!['OTHER','SELL','BUY'].includes(result.decision)){console.log('Invalid result - decision: '+result.decision)console.log('Invalid result - json: '+JSON.stringify(result,null,3))result.decision='OTHER'}if(result.decision&&['SELL','BUY'].includes(result.decision)){console.log(`Result - decision: ${result.decision}`)console.log(`Result - confident: ${result.confident}`)console.log(`Result - reason: ${result.reason}`)}if(result.decision=='BUY'){awaitbth.buy()}elseif(result.decision=='SELL'){awaitbth.sell()}}else{// Here is your code to analyze the potential support candles,// if they have been defined (aka supportHistoricalData)}}asyncfunctionsleep(ms: number){returnnewPromise((resolve)=>setTimeout(resolve,ms))}functionroundTo(value: number,digit: number=2){constfactor=Math.pow(10,digit)returnMath.ceil(value*factor)/factor}
main.ts
import{parseRunResultsStats,findHistoricalData,findHistoricalDataNames,downloadHistoricalData,runStrategy,scanStrategies,printInfo}from'@backtest/framework'asyncfunctionmain(){printInfo()// historical dataconststartDate=newDate('2024-01-01').getTime()constendDate=newDate('2024-10-15').getTime()// analyzed periodconststartTime=newDate('2024-08-01').getTime()constendTime=newDate('2024-10-14').getTime()constfound=awaitfindHistoricalData('BTCEUR-8h')console.log('found:',found)if(!found){constdownloaded=awaitdownloadHistoricalData('BTCEUR',{interval: '8h',startDate: startDate,endDate: endDate})console.log('downloaded:',downloaded)}constallNames=awaitfindHistoricalDataNames()console.log('allNames:',allNames)constscan=awaitscanStrategies()console.log('scan:',scan)constpercentFee=0.15constpercentSlippage=1.5// Note: The values for percentage fee and slippage are also passed as parameters// so they can be included as data in the prompt for MistralconststrategyResult=awaitrunStrategy({strategyName: 'simple',historicalData: ['BTCEUR-8h'],params: {percentFee: percentFee,percentSlippage: percentSlippage},percentFee: percentFee,percentSlippage: percentSlippage,startingAmount: 1000,startTime: startTime,endTime: endTime})constparsed=awaitparseRunResultsStats(strategyResult)console.log('parsed:',parsed?.totals[0],parsed?.totals[1])// just to show somethings (probably, you need to look parsed or strategyResult)}main()
If this project, example, or other information has been helpful to you, please consider supporting us through a donation or by contributing to the code. You can find more information here ❤️
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hello,
this is an example of how to integrate Mistral AI APIs with backtest framework .
Pay attention
The prompt is intentionally simple, as are the provided data. The idea is just to show how you can use Mistral AI and backtestJS together, so do not use this prompt in production.
Below, are all the necessary files, you can use the "quick-start" project as a quick base:
simple.ts
file and insert the content you find below.main.ts
as shown in the example below..env
file as needed.By running
npm run dev
, you will see something similar in the console:simple.ts
main.ts
.env
If this project, example, or other information has been helpful to you, please consider supporting us through a donation or by contributing to the code. You can find more information here ❤️
Beta Was this translation helpful? Give feedback.
All reactions