Skip to content

FEATURE: [sync] Sync futures positions in DB#2506

Merged
dboyliao merged 6 commits into
mainfrom
dboy/sync/futures-position-risk
May 30, 2026
Merged

FEATURE: [sync] Sync futures positions in DB#2506
dboyliao merged 6 commits into
mainfrom
dboy/sync/futures-position-risk

Conversation

@dboyliao
Copy link
Copy Markdown
Collaborator

  • Bugfix: incorrect time conversion in query futures closed orders
  • Implement driver.Valuer and Scanner interface for types.MillisecondTimestamp
  • Migrations for futures position risk table
  • Implement syncing futures position risks

@dboyliao dboyliao requested a review from c9s May 28, 2026 08:10
`open_order_initial_margin` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`adl` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`margin_asset` VARCHAR(20) NOT NULL DEFAULT '',
`update_time` DATETIME(3) NOT NULL,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

use updated_at

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done.

`maint_margin` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`position_initial_margin` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`open_order_initial_margin` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`adl` DECIMAL(16, 8) NOT NULL DEFAULT 0,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

do we need 8 precision for just ADL?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.
It's now just 2 precision for ADL.

`initial_margin` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`maint_margin` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`position_initial_margin` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`open_order_initial_margin` DECIMAL(16, 8) NOT NULL DEFAULT 0,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

for usd based unit, do we really need 8 fraction numbers?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed. It's 2 now.

`mark_price` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`break_even_price` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`position_amount` DECIMAL(16, 8) NOT NULL DEFAULT 0,
`unrealized_pnl` DECIMAL(16, 8) NOT NULL DEFAULT 0,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

%.2f is already enough i think

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done.

@dboyliao dboyliao force-pushed the dboy/sync/futures-position-risk branch from d4481c7 to 23eefa2 Compare May 29, 2026 01:39
@dboyliao dboyliao requested a review from c9s May 29, 2026 01:41
`unrealized_pnl` DECIMAL(16, 2) NOT NULL DEFAULT 0,
`notional` DECIMAL(16, 2) NOT NULL DEFAULT 0,
`initial_margin` DECIMAL(16, 2) NOT NULL DEFAULT 0,
`maint_margin` DECIMAL(16, 2) NOT NULL DEFAULT 0,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

sqlite doesn't support DECIMAL(16, 2), just DECIMAL i think, you can use AI to fix your query

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Opps, I didn't notice that.
This query is generated by AI.
Will fix it.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Can you add the process as a Claude skill, like add-migration? so that we can reuse it

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done.
Please refer to .claude/skills/add-migration.

Comment thread pkg/bbgo/environment.go Outdated
}
}

futuresPositionWroterCreator := func(session *ExchangeSession) func(types.Trade) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

should be called XXXWriterCreator ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

Comment thread pkg/bbgo/environment.go Outdated
Comment on lines +434 to +444
if environ.SyncService == nil || environ.SyncService.FuturesPositionRiskService == nil {
return
}

service, ok := session.Exchange.(types.ExchangeRiskService)
if !ok {
return
}
if !(trade.IsFutures || trade.IsIsolated) {
return
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

these checks can be done before setting this closure i think
you only need this callback for futures session

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done.

Comment thread pkg/bbgo/environment.go Outdated
return
}

lastTradeTime = trade.Time.Time()
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

since you need to store the lastTradeTime variable, I would prefer you pull out this code, and add it in the FuturesService as a method like "QueryAndInsert(exchange, ...)", pass the exchange instance to the sync service to query and insert

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done.

Comment thread pkg/bbgo/environment.go
orderWriter := orderWriterCreator(s2)
session.UserDataStream.OnOrderUpdate(orderWriter)
}
if config.UserDataStream.FuturesPosition {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done.

Comment thread pkg/bbgo/environment.go Outdated
MarginService: environ.MarginService,
WithdrawService: &service.WithdrawService{DB: db},
DepositService: &service.DepositService{DB: db},
FuturesPositionRiskService: &service.FuturesPositionRiskService{DB: db},
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

maybe just name it FuturesService to include all futures related sync methods, or you have to add more service for other futures api

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done.

Comment thread pkg/service/futures.go Outdated

func (s *FuturesPositionRiskService) Sync(
ctx context.Context,
exchange types.Exchange, symbol string,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

use type types.ExchangeRiskService for the parameter, force the api caller to convert the object into this interface to call this method.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done

Comment thread pkg/service/futures.go Outdated
func (s *FuturesPositionRiskService) Sync(
ctx context.Context,
exchange types.Exchange, symbol string,
startTime, endTime time.Time,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

startTime and endTime are not used?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

If they are not being used in the current moment, please remove them.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

done.

@dboyliao dboyliao force-pushed the dboy/sync/futures-position-risk branch 2 times, most recently from 5ed5c13 to fd60860 Compare May 29, 2026 14:56
@dboyliao dboyliao requested a review from c9s May 29, 2026 15:30
@dboyliao dboyliao force-pushed the dboy/sync/futures-position-risk branch from 9ccb98e to 44eac99 Compare May 30, 2026 01:58
@dboyliao dboyliao force-pushed the dboy/sync/futures-position-risk branch from 44eac99 to 9d38c04 Compare May 30, 2026 02:00
@dboyliao dboyliao merged commit 985f9cf into main May 30, 2026
3 checks passed
@dboyliao dboyliao deleted the dboy/sync/futures-position-risk branch May 30, 2026 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants