mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
strategy/linregmaker: works w/o dynamic qty
This commit is contained in:
parent
e776c9e5ea
commit
cc124d4264
|
@ -110,7 +110,7 @@ exchangeStrategies:
|
||||||
domain: [ -1, 1 ]
|
domain: [ -1, 1 ]
|
||||||
# when in down band, holds 1.0 by maximum
|
# when in down band, holds 1.0 by maximum
|
||||||
# when in up band, holds 0.05 by maximum
|
# when in up band, holds 0.05 by maximum
|
||||||
range: [ 10.0, 1.0 ]
|
range: [ 1.0, 1.0 ]
|
||||||
|
|
||||||
# quantity is the base order quantity for your buy/sell order.
|
# quantity is the base order quantity for your buy/sell order.
|
||||||
quantity: 0.1
|
quantity: 0.1
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package dynamicmetric
|
|
||||||
|
|
||||||
import "github.com/c9s/bbgo/pkg/types"
|
|
||||||
|
|
||||||
// BollingerSetting is for Bollinger Band settings
|
|
||||||
type BollingerSetting struct {
|
|
||||||
types.IntervalWindow
|
|
||||||
BandWidth float64 `json:"bandWidth"`
|
|
||||||
}
|
|
|
@ -16,18 +16,6 @@ type DynamicSpread struct {
|
||||||
|
|
||||||
// WeightedBollWidthRatioSpread calculates spreads based on two Bollinger Bands
|
// WeightedBollWidthRatioSpread calculates spreads based on two Bollinger Bands
|
||||||
WeightedBollWidthRatioSpread *DynamicSpreadBollWidthRatio `json:"weightedBollWidth"`
|
WeightedBollWidthRatioSpread *DynamicSpreadBollWidthRatio `json:"weightedBollWidth"`
|
||||||
|
|
||||||
// deprecated
|
|
||||||
Enabled *bool `json:"enabled"`
|
|
||||||
|
|
||||||
// deprecated
|
|
||||||
types.IntervalWindow
|
|
||||||
|
|
||||||
// deprecated. AskSpreadScale is used to define the ask spread range with the given percentage.
|
|
||||||
AskSpreadScale *bbgo.PercentageScale `json:"askSpreadScale"`
|
|
||||||
|
|
||||||
// deprecated. BidSpreadScale is used to define the bid spread range with the given percentage.
|
|
||||||
BidSpreadScale *bbgo.PercentageScale `json:"bidSpreadScale"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize dynamic spread
|
// Initialize dynamic spread
|
||||||
|
@ -37,14 +25,6 @@ func (ds *DynamicSpread) Initialize(symbol string, session *bbgo.ExchangeSession
|
||||||
ds.AmpSpread.initialize(symbol, session)
|
ds.AmpSpread.initialize(symbol, session)
|
||||||
case ds.WeightedBollWidthRatioSpread != nil:
|
case ds.WeightedBollWidthRatioSpread != nil:
|
||||||
ds.WeightedBollWidthRatioSpread.initialize(symbol, session)
|
ds.WeightedBollWidthRatioSpread.initialize(symbol, session)
|
||||||
case ds.Enabled != nil && *ds.Enabled:
|
|
||||||
// backward compatibility
|
|
||||||
ds.AmpSpread = &DynamicSpreadAmp{
|
|
||||||
IntervalWindow: ds.IntervalWindow,
|
|
||||||
AskSpreadScale: ds.AskSpreadScale,
|
|
||||||
BidSpreadScale: ds.BidSpreadScale,
|
|
||||||
}
|
|
||||||
ds.AmpSpread.initialize(symbol, session)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,8 +151,8 @@ type DynamicSpreadBollWidthRatio struct {
|
||||||
// A positive number. The greater factor, the sharper weighting function. Default set to 1.0 .
|
// A positive number. The greater factor, the sharper weighting function. Default set to 1.0 .
|
||||||
Sensitivity float64 `json:"sensitivity"`
|
Sensitivity float64 `json:"sensitivity"`
|
||||||
|
|
||||||
DefaultBollinger *BollingerSetting `json:"defaultBollinger"`
|
DefaultBollinger types.IntervalWindowBandWidth `json:"defaultBollinger"`
|
||||||
NeutralBollinger *BollingerSetting `json:"neutralBollinger"`
|
NeutralBollinger types.IntervalWindowBandWidth `json:"neutralBollinger"`
|
||||||
|
|
||||||
neutralBoll *indicator.BOLL
|
neutralBoll *indicator.BOLL
|
||||||
defaultBoll *indicator.BOLL
|
defaultBoll *indicator.BOLL
|
||||||
|
@ -232,7 +212,7 @@ func (ds *DynamicSpreadBollWidthRatio) getWeightedBBWidthRatio(positiveSigmoid b
|
||||||
// - To bid spread, the weighting density function d_weight(x) is sigmoid((default_BB_mid - x) / (w / alpha))
|
// - To bid spread, the weighting density function d_weight(x) is sigmoid((default_BB_mid - x) / (w / alpha))
|
||||||
// - The higher sensitivity factor alpha, the sharper weighting function.
|
// - The higher sensitivity factor alpha, the sharper weighting function.
|
||||||
//
|
//
|
||||||
// Then calculate the weighted band width ratio by taking integral of d_weight(x) from neutral_BB_lower to neutral_BB_upper:
|
// Then calculate the weighted bandwidth ratio by taking integral of d_weight(x) from neutral_BB_lower to neutral_BB_upper:
|
||||||
// infinite integral of ask spread sigmoid weighting density function F(x) = (w / alpha) * ln(exp(x / (w / alpha)) + exp(default_BB_mid / (w / alpha)))
|
// infinite integral of ask spread sigmoid weighting density function F(x) = (w / alpha) * ln(exp(x / (w / alpha)) + exp(default_BB_mid / (w / alpha)))
|
||||||
// infinite integral of bid spread sigmoid weighting density function F(x) = x - (w / alpha) * ln(exp(x / (w / alpha)) + exp(default_BB_mid / (w / alpha)))
|
// infinite integral of bid spread sigmoid weighting density function F(x) = x - (w / alpha) * ln(exp(x / (w / alpha)) + exp(default_BB_mid / (w / alpha)))
|
||||||
// Note that we've rescaled the sigmoid function to fit default BB,
|
// Note that we've rescaled the sigmoid function to fit default BB,
|
||||||
|
|
|
@ -25,17 +25,12 @@ var two = fixedpoint.NewFromInt(2)
|
||||||
var log = logrus.WithField("strategy", ID)
|
var log = logrus.WithField("strategy", ID)
|
||||||
|
|
||||||
//TODO: Logic for backtest
|
//TODO: Logic for backtest
|
||||||
|
// TODO: Dynamic exposure should work on both side
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
bbgo.RegisterStrategy(ID, &Strategy{})
|
bbgo.RegisterStrategy(ID, &Strategy{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove BollingerSetting and bollsetting.go
|
|
||||||
type BollingerSetting struct {
|
|
||||||
types.IntervalWindow
|
|
||||||
BandWidth float64 `json:"bandWidth"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Strategy struct {
|
type Strategy struct {
|
||||||
Environment *bbgo.Environment
|
Environment *bbgo.Environment
|
||||||
StandardIndicatorSet *bbgo.StandardIndicatorSet
|
StandardIndicatorSet *bbgo.StandardIndicatorSet
|
||||||
|
@ -77,7 +72,10 @@ type Strategy struct {
|
||||||
// NeutralBollinger is the smaller range of the bollinger band
|
// NeutralBollinger is the smaller range of the bollinger band
|
||||||
// If price is in this band, it usually means the price is oscillating.
|
// If price is in this band, it usually means the price is oscillating.
|
||||||
// If price goes out of this band, we tend to not place sell orders or buy orders
|
// If price goes out of this band, we tend to not place sell orders or buy orders
|
||||||
NeutralBollinger *BollingerSetting `json:"neutralBollinger"`
|
NeutralBollinger types.IntervalWindowBandWidth `json:"neutralBollinger"`
|
||||||
|
|
||||||
|
// neutralBoll is the neutral price section for TradeInBand
|
||||||
|
neutralBoll *indicator.BOLL
|
||||||
|
|
||||||
// TradeInBand
|
// TradeInBand
|
||||||
// When this is on, places orders only when the current price is in the bollinger band.
|
// When this is on, places orders only when the current price is in the bollinger band.
|
||||||
|
@ -113,7 +111,7 @@ type Strategy struct {
|
||||||
DynamicExposure dynamicmetric.DynamicExposure `json:"dynamicExposure"`
|
DynamicExposure dynamicmetric.DynamicExposure `json:"dynamicExposure"`
|
||||||
|
|
||||||
bbgo.QuantityOrAmount
|
bbgo.QuantityOrAmount
|
||||||
// TODO: Should work w/o dynamic qty
|
|
||||||
// DynamicQuantityIncrease calculates the increase position order quantity dynamically
|
// DynamicQuantityIncrease calculates the increase position order quantity dynamically
|
||||||
DynamicQuantityIncrease dynamicmetric.DynamicQuantitySet `json:"dynamicQuantityIncrease"`
|
DynamicQuantityIncrease dynamicmetric.DynamicQuantitySet `json:"dynamicQuantityIncrease"`
|
||||||
|
|
||||||
|
@ -134,9 +132,6 @@ type Strategy struct {
|
||||||
|
|
||||||
groupID uint32
|
groupID uint32
|
||||||
|
|
||||||
// neutralBoll is the neutral price section
|
|
||||||
neutralBoll *indicator.BOLL
|
|
||||||
|
|
||||||
// StrategyController
|
// StrategyController
|
||||||
bbgo.StrategyController
|
bbgo.StrategyController
|
||||||
}
|
}
|
||||||
|
@ -176,7 +171,7 @@ func (s *Strategy) Subscribe(session *bbgo.ExchangeSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscribe for BBs
|
// Subscribe for BBs
|
||||||
if s.NeutralBollinger != nil && s.NeutralBollinger.Interval != "" {
|
if s.NeutralBollinger.Interval != "" {
|
||||||
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{
|
session.Subscribe(types.KLineChannel, s.Symbol, types.SubscribeOptions{
|
||||||
Interval: s.NeutralBollinger.Interval,
|
Interval: s.NeutralBollinger.Interval,
|
||||||
})
|
})
|
||||||
|
@ -276,39 +271,38 @@ func (s *Strategy) getOrderPrices(midPrice fixedpoint.Value) (askPrice fixedpoin
|
||||||
func (s *Strategy) getOrderQuantities(askPrice fixedpoint.Value, bidPrice fixedpoint.Value) (sellQuantity fixedpoint.Value, buyQuantity fixedpoint.Value) {
|
func (s *Strategy) getOrderQuantities(askPrice fixedpoint.Value, bidPrice fixedpoint.Value) (sellQuantity fixedpoint.Value, buyQuantity fixedpoint.Value) {
|
||||||
// TODO: spot, margin, and futures
|
// TODO: spot, margin, and futures
|
||||||
|
|
||||||
|
// Default
|
||||||
|
sellQuantity = s.QuantityOrAmount.CalculateQuantity(askPrice)
|
||||||
|
buyQuantity = s.QuantityOrAmount.CalculateQuantity(bidPrice)
|
||||||
|
|
||||||
// Dynamic qty
|
// Dynamic qty
|
||||||
switch {
|
switch {
|
||||||
case s.mainTrendCurrent == types.DirectionUp:
|
case s.mainTrendCurrent == types.DirectionUp:
|
||||||
var err error
|
|
||||||
if len(s.DynamicQuantityIncrease) > 0 {
|
if len(s.DynamicQuantityIncrease) > 0 {
|
||||||
buyQuantity, err = s.DynamicQuantityIncrease.GetQuantity()
|
qty, err := s.DynamicQuantityIncrease.GetQuantity()
|
||||||
if err != nil {
|
if err == nil {
|
||||||
buyQuantity = s.QuantityOrAmount.CalculateQuantity(bidPrice)
|
buyQuantity = qty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(s.DynamicQuantityDecrease) > 0 {
|
if len(s.DynamicQuantityDecrease) > 0 {
|
||||||
sellQuantity, err = s.DynamicQuantityDecrease.GetQuantity()
|
qty, err := s.DynamicQuantityDecrease.GetQuantity()
|
||||||
if err != nil {
|
if err == nil {
|
||||||
sellQuantity = s.QuantityOrAmount.CalculateQuantity(askPrice)
|
sellQuantity = qty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case s.mainTrendCurrent == types.DirectionDown:
|
case s.mainTrendCurrent == types.DirectionDown:
|
||||||
var err error
|
|
||||||
if len(s.DynamicQuantityIncrease) > 0 {
|
if len(s.DynamicQuantityIncrease) > 0 {
|
||||||
sellQuantity, err = s.DynamicQuantityIncrease.GetQuantity()
|
qty, err := s.DynamicQuantityIncrease.GetQuantity()
|
||||||
if err != nil {
|
if err == nil {
|
||||||
sellQuantity = s.QuantityOrAmount.CalculateQuantity(bidPrice)
|
sellQuantity = qty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(s.DynamicQuantityDecrease) > 0 {
|
if len(s.DynamicQuantityDecrease) > 0 {
|
||||||
buyQuantity, err = s.DynamicQuantityDecrease.GetQuantity()
|
qty, err := s.DynamicQuantityDecrease.GetQuantity()
|
||||||
if err != nil {
|
if err == nil {
|
||||||
buyQuantity = s.QuantityOrAmount.CalculateQuantity(askPrice)
|
buyQuantity = qty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
sellQuantity = s.QuantityOrAmount.CalculateQuantity(askPrice)
|
|
||||||
buyQuantity = s.QuantityOrAmount.CalculateQuantity(bidPrice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Faster position decrease
|
// Faster position decrease
|
||||||
|
|
Loading…
Reference in New Issue
Block a user