Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ jobs:
python-version: 3.10.x
architecture: x64

- uses: actions/setup-node@v6
with:
node-version: 22

- name: Install dependencies
run: pip install --prefer-binary -r dev_requirements.txt -r requirements.txt

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ wheels/
.installed.cfg
*.egg

node_modules

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
Expand Down Expand Up @@ -136,6 +138,7 @@ cython_debug/
.env

*.zip
*.db

# tensorboard
tensorboard_logs
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] - 2026-02-27
### Added
- Support for services tentacles
- Support for profile scripting
### Updated
- Report redesign

## [0.0.29] - 2025-12-29
### Updated
- OctoBot to 2.0.16
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
recursive-include octobot_script/config *.json *.ini
recursive-include octobot_script/resources *.js *.css *.html
recursive-exclude octobot_script/resources/report/node_modules *
recursive-exclude octobot_script/resources/report/src *

include README.md
include LICENSE
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# OctoBot-Script [0.0.29](https://github.com/Drakkar-Software/OctoBot-Script/tree/master/CHANGELOG.md)
# OctoBot-Script [0.1.0](https://github.com/Drakkar-Software/OctoBot-Script/tree/master/CHANGELOG.md)
[![PyPI](https://img.shields.io/pypi/v/OctoBot-Script.svg?logo=pypi)](https://pypi.python.org/pypi/octobot-script/)
[![Downloads](https://static.pepy.tech/badge/OctoBot-Script/month)](https://pepy.tech/project/octobot-script)
[![Dockerhub](https://img.shields.io/docker/pulls/drakkarsoftware/OctoBot-Script.svg?logo=docker)](https://hub.docker.com/r/drakkarsoftware/octobot-script)
Expand Down Expand Up @@ -91,3 +91,12 @@ asyncio.run(rsi_test())
We recently created a telegram channel dedicated to OctoBot Script.

[![Telegram News](https://img.shields.io/static/v1?label=Telegram%20chat&message=Join&logo=telegram&&color=007bff&style=for-the-badge)](https://t.me/+366CLLZ2NC0xMjFk)

### Developers

To build report from sources:

```bash
npm install
npm run build
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

```
42 changes: 42 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.8/schema.json",
"assist": { "actions": { "source": { "organizeImports": "on" } } },
"files": {
"includes": [
"**",
"!**/dist/**/*",
"!**/node_modules/**/*",
"!**/src/components/ui/**/*"
]
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "off",
"noArrayIndexKey": "off"
},
"style": {
"noNonNullAssertion": "off",
"noParameterAssign": "error",
"useSelfClosingElements": "error",
"noUselessElse": "error"
}
}
},
"formatter": {
"indentStyle": "space"
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"semicolons": "asNeeded"
}
},
"css": {
"parser": {
"tailwindDirectives": true
}
}
}
23 changes: 23 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "octobot_script/resources/report/src/index.css",
"baseColor": "gray",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"rtl": false,
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
61 changes: 36 additions & 25 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
import asyncio
import tulipy # Can be any TA library.
import tulipy # Can be any TA library.
import octobot_script as obs


async def rsi_test():
async def example():
async def initialize(ctx):
# Compute entries only once per backtest.
closes = await obs.Close(ctx, max_history=True)
times = await obs.Time(ctx, max_history=True, use_close_time=True)
rsi_v = tulipy.rsi(closes, period=ctx.tentacle.trading_config["period"])
delta = len(closes) - len(rsi_v)
# Populate entries with timestamps of candles where RSI is
# bellow the "rsi_value_buy_threshold" configuration.
run_data["entries"] = {
times[index + delta]
for index, rsi_val in enumerate(rsi_v)
if rsi_val < ctx.tentacle.trading_config["rsi_value_buy_threshold"]
}
await obs.plot_indicator(ctx, "RSI", times[delta:], rsi_v, run_data["entries"])

async def strategy(ctx):
# Will be called at each candle.
if run_data["entries"] is None:
# Compute entries only once per backtest.
closes = await obs.Close(ctx, max_history=True)
times = await obs.Time(ctx, max_history=True, use_close_time=True)
rsi_v = tulipy.rsi(closes, period=ctx.tentacle.trading_config["period"])
delta = len(closes) - len(rsi_v)
# Populate entries with timestamps of candles where RSI is
# bellow the "rsi_value_buy_threshold" configuration.
run_data["entries"] = {
times[index + delta]
for index, rsi_val in enumerate(rsi_v)
if rsi_val < ctx.tentacle.trading_config["rsi_value_buy_threshold"]
}
await obs.plot_indicator(ctx, "RSI", times[delta:], rsi_v, run_data["entries"])
# Called at each candle.
# Uses pre-computed entries times to enter positions when relevant.
# Also, instantly set take profits and stop losses.
# Position exits could also be set separately.
if obs.current_live_time(ctx) in run_data["entries"]:
# Uses pre-computed entries times to enter positions when relevant.
# Also, instantly set take profits and stop losses.
# Position exists could also be set separately.
await obs.market(ctx, "buy", amount="10%", stop_loss_offset="-15%", take_profit_offset="25%")
await obs.market(
ctx,
"buy",
amount="10%",
stop_loss_offset="-15%",
take_profit_offset="25%",
)

# Configuration that will be passed to each run.
# It will be accessible under "ctx.tentacle.trading_config".
Expand All @@ -34,19 +41,23 @@ async def strategy(ctx):
}

# Read and cache candle data to make subsequent backtesting runs faster.
data = await obs.get_data("BTC/USDT", "1d", start_timestamp=1505606400)
data = await obs.get_data(
"BTC/USDT", "1d", start_timestamp=1505606400, social_services=[]
)
run_data = {
"entries": None,
}
# Run a backtest using the above data, strategy and configuration.
res = await obs.run(data, strategy, config)
res = await obs.run(
data, config, initialize_func=initialize, strategy_func=strategy
)
print(res.describe())
# Generate and open report including indicators plots
await res.plot(show=True)
await obs.generate_and_show_report(res)
# Stop data to release local databases.
await data.stop()


# Call the execution of the script inside "asyncio.run" as
# OctoBot-Script runs using the python asyncio framework.
asyncio.run(rsi_test())
asyncio.run(example())
2 changes: 1 addition & 1 deletion octobot_script/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

PROJECT_NAME = "OctoBot-Script"
AUTHOR = "Drakkar-Software"
VERSION = "0.0.29" # major.minor.revision => don't forget to also update the setup.py version
VERSION = "0.1.0" # major.minor.revision => don't forget to also update the setup.py version


def _use_module_local_tentacles():
Expand Down
Loading