Skip to content

Commit

Permalink
adjust timeframe
Browse files Browse the repository at this point in the history
  • Loading branch information
adyzng committed Dec 29, 2017
1 parent 5b225ae commit c5fb629
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 42 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ testdata/
output*
debug/
test/
MQL4/
9 changes: 7 additions & 2 deletions core/timeframe.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,16 @@ func (tf *Timeframe) worker() error {
tickSeconds = uint32(tick.Timestamp / 1000)
tickBarTime = tickSeconds - tickSeconds%tf.deltaTimestamp

if tf.startTimestamp == 0 {
tf.startTimestamp = tickBarTime
tf.endTimestamp = tickBarTime + tf.deltaTimestamp
}

//Determines the end of the current bar.
if tickSeconds >= tf.endTimestamp {
// output one bar data
if len(barTicks) > 0 {
tf.out.PackTicks(tickBarTime, barTicks[:])
tf.out.PackTicks(tf.startTimestamp, barTicks[:])
barTicks = barTicks[:0]
}

Expand All @@ -121,7 +126,7 @@ func (tf *Timeframe) worker() error {
}

if len(barTicks) > 0 {
tf.out.PackTicks(tickBarTime, barTicks[:])
tf.out.PackTicks(tf.startTimestamp, barTicks[:])
}

return nil
Expand Down
58 changes: 44 additions & 14 deletions fxt4/fxt4.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"fmt"
"math"
"os"
"path/filepath"

Expand Down Expand Up @@ -41,7 +42,7 @@ type FxtFile struct {

// NewFxtFile create an new fxt file instance
func NewFxtFile(timeframe, spread, model uint32, dest, symbol string) *FxtFile {
fn := fmt.Sprintf("%s%02d_%d.fxt", symbol, timeframe, model)
fn := fmt.Sprintf("%s%d_%d.fxt", symbol, timeframe, model)
fxt := &FxtFile{
header: NewHeader(405, symbol, timeframe, spread, model),
fpath: filepath.Join(dest, fn),
Expand All @@ -60,7 +61,7 @@ func NewFxtFile(timeframe, spread, model uint32, dest, symbol string) *FxtFile {
func (f *FxtFile) worker() error {
defer func() {
close(f.chClose)
log.Info("M5d Saved Bar: %d, Ticks: %d.", f.timeframe, f.barCount, f.tickCount)
log.Info("M%d Saved Bar: %d, Ticks: %d.", f.timeframe, f.barCount, f.tickCount)
}()

fxt, err := os.OpenFile(f.fpath, os.O_CREATE|os.O_TRUNC, 666)
Expand All @@ -70,17 +71,27 @@ func (f *FxtFile) worker() error {
}

defer fxt.Close()
bu := bytes.NewBuffer(make([]byte, 0, 4096))
bu := bytes.NewBuffer(make([]byte, 0, headerSize))

//
// write FXT header
// convert FXT header
//
if err = binary.Write(bu, binary.LittleEndian, f.header); err != nil {
log.Error("Convert FXT header failed: %v.", err)
return err
}
// write FXT file
if _, err := fxt.Write(bu.Bytes()); err != nil {
log.Error("Write FXT header failed: %v.", err)
return err
}

for tick := range f.chTicks {

if tick.BarTimestamp > tick.TickTimestamp {
log.Fatal("Tick(%v)", tick)
}

bu.Reset()
//
// write tick data
Expand All @@ -89,31 +100,46 @@ func (f *FxtFile) worker() error {
log.Error("Pack tick failed: %v.", err)
break
}
if _, err = fxt.Write(bu.Bytes()); err != nil {
log.Error("Write fxt tick (%x) failed: %v.", bu.Bytes(), err)
break
}

if f.firstUniBar == nil {
f.firstUniBar = tick
}
f.lastUniBar = tick

if _, err = fxt.Write(bu.Bytes()); err != nil {
log.Error("Write fxt tick (%x) failed: %v.", bu.Bytes(), err)
break
}
}
return err
}

func (f *FxtFile) PackTicks(barTimestemp uint32, ticks []*core.TickData) error {

if len(ticks) == 0 {
return nil
}

var (
op = ticks[0].Bid
hi = ticks[0].Bid
lo = ticks[0].Bid
vo = math.Max(ticks[0].VolumeBid, 1)
)

for _, tick := range ticks {
f.chTicks <- &FxtTick{
ft := &FxtTick{
BarTimestamp: uint32(barTimestemp),
TickTimestamp: uint32(tick.Timestamp / 1000),
Open: tick.Bid,
High: tick.Bid,
Low: tick.Bid,
Open: op,
High: math.Max(tick.Bid, hi),
Low: math.Min(tick.Bid, lo),
Close: tick.Bid,
Volume: uint64(tick.VolumeBid),
Volume: uint64(vo),
//RealSpread: uint32(tick.Ask - tick.Bid/f.header.PointSize),
//LaunchExpert: 3,
}
vo = vo + tick.VolumeBid
f.chTicks <- ft
f.tickCount++
}
if f.endTimestamp != barTimestemp {
Expand All @@ -124,6 +150,10 @@ func (f *FxtFile) PackTicks(barTimestemp uint32, ticks []*core.TickData) error {
}

func (f *FxtFile) adjustHeader() error {
if f.barCount == 0 {
return nil
}

fxt, err := os.OpenFile(f.fpath, os.O_RDWR, 666)
if err != nil {
log.Fatal("Open file %s failed: %v.", f.fpath, err)
Expand Down
14 changes: 10 additions & 4 deletions fxt4/fxt4_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ import (
)

func TestFxtFile(t *testing.T) {
fn := 1e-5 + 0.123
fmt.Println(fn)

fxt := NewFxtFile(1, 20, 0, "D:\\Data", "EURUSD")
fxt.PackTicks(0, []*core.TickData{&core.TickData{}})
}

func TestHeader(t *testing.T) {
//fname := `F:\tester-ok\EURUSD1_0.fxt`
fname := `E:\test\EURUSD5_0.fxt`
fname := `F:\201710\EURUSD1_0.fxt`
//fname := `F:\201710\EURUSD1.fxt`
//fname := `C:\Users\huan\AppData\Roaming\MetaQuotes\Terminal\1DAFD9A7C67DC84FE37EAA1FC1E5CF75\tester\history\EURUSD1_0.fxt`

fh, err := os.OpenFile(fname, os.O_RDONLY, 666)
if err != nil {
Expand All @@ -38,6 +42,8 @@ func TestHeader(t *testing.T) {
t.Fatalf("Decode fxt header failed: %v.\n", err)
}

fmt.Printf("Header:\n%+v\n", h)

tickBs := make([]byte, tickSize)
for {
n, err = fh.Read(tickBs[:tickSize])
Expand All @@ -57,7 +63,7 @@ func TestHeader(t *testing.T) {
break
}

fmt.Println(tick)
fmt.Println(&tick)
//break
}
fmt.Printf("Header:\n%+v\n", h)
}
66 changes: 48 additions & 18 deletions fxt4/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type FXTHeader struct {
BaseCurrency [12]byte // 240 12 base currency (szchar) = StringLeft(symbol, 3)
Spread uint32 // 252 4 spread in points: 0=zero spread = MarketInfo(MODE_SPREAD)
Digits uint32 // 256 4 digits = MarketInfo(MODE_DIGITS)
Reserved2 [4]byte // 260 4 (alignment to the next double)
_ [4]byte // 260 4 (alignment to the next double)
PointSize float64 // 264 8 resolution, ie. 0.0000'1 = MarketInfo(MODE_POINT)
MinLotsize uint32 // 272 4 min lot size in centi lots (hundredths) = MarketInfo(MODE_MINLOT) * 100
MaxLotsize uint32 // 276 4 max lot size in centi lots (hundredths) = MarketInfo(MODE_MAXLOT) * 100
Expand Down Expand Up @@ -103,18 +103,16 @@ type FxtTick struct {
LaunchExpert uint32 // 52 4
}

func (t FxtTick) String() string {
bt := time.Unix(int64(t.BarTimestamp), 0).UTC()
tt := time.Unix(int64(t.TickTimestamp), 0).UTC()
return fmt.Sprintf("%s %s %f %f %f %f %d",
bt.Format("2006-01-02 15:04:05"),
tt.Format("2006-01-02 15:04:05"),
t.Open,
t.High,
t.Low,
t.Close,
t.Volume,
)
type FxtTick_ struct {
BarTimestamp uint32 // 0 4
Open float64 // 4 8
High float64 // 12 8
Low float64 // 20 8
Close float64 // 28 8
Volume uint64 // 36 8
RealSpread uint32 // 44 4
TickTimestamp uint32 // 48 4
LaunchExpert uint32 // 52 4
}

// NewHeader return an predefined FXT header
Expand All @@ -136,16 +134,16 @@ func NewHeader(version uint32, symbol string, timeframe, spread, model uint32) *
PendingsGTC: 1,

// Profit Calculation parameters.
ContractSize: 100000.0,
TickValue: 0.0,
TickSize: 0.0,
ContractSize: 100000,
TickValue: 0,
TickSize: 0,
ProfitCalculationMode: 0,

// Swap calculation
SwapEnabled: 0,
SwapCalculationMode: 0,
SwapLongValue: 0.0,
SwapShortValue: 0.0,
SwapLongValue: 0,
SwapShortValue: 0,
TripleRolloverDay: 3,

// Margin calculation.
Expand Down Expand Up @@ -176,3 +174,35 @@ func NewHeader(version uint32, symbol string, timeframe, spread, model uint32) *

return h
}

func (h *FXTHeader) ToBytes() ([]byte, error) {
bs, err := misc.PackLittleEndian(headerSize, h)
if err != nil {
log.Error("Failed to convert FXT header to bytes array. Error %v.", err)
return make([]byte, 0), err
}
return bs, err
}

func (t *FxtTick) ToBytes() ([]byte, error) {
bs, err := misc.PackLittleEndian(tickSize, t)
if err != nil {
log.Error("Failed to convert FXT tick to bytes array. Error %v.", err)
return make([]byte, 0), err
}
return bs, err
}

func (t *FxtTick) String() string {
bt := time.Unix(int64(t.BarTimestamp), 0).UTC()
tt := time.Unix(int64(t.TickTimestamp), 0).UTC()
return fmt.Sprintf("%s %s %f %f %f %f %d",
bt.Format("2006-01-02 15:04:05"),
tt.Format("2006-01-02 15:04:05"),
t.Open,
t.High,
t.Low,
t.Close,
t.Volume,
)
}
2 changes: 1 addition & 1 deletion hst/hst401.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (h *HST401) PackTicks(barTimestamp uint32, ticks []*core.TickData) error {

select {
case h.chBars <- bar:
log.Trace("Bar %d: %v.", h.barCount, bar)
//log.Trace("Bar %d: %v.", h.barCount, bar)
h.barCount++
break
//case <-h.close:
Expand Down
7 changes: 4 additions & 3 deletions hst/hst401_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ func TestHSTHeader(t *testing.T) {
}

func TestLoadHst(t *testing.T) {
//fname := "F:\\00\\EURUSD1.hst"
fcsv := "F:\\00\\EURUSD30-correct.csv"
fname := "C:\\Users\\huan\\AppData\\Roaming\\MetaQuotes\\Terminal\\1DAFD9A7C67DC84FE37EAA1FC1E5CF75\\history\\ICMarkets-Demo01\\00\\EURUSD30.hst"

fcsv := `F:\201710\EURUSD1.hst.csv`
fname := `F:\201710\EURUSD1.hst`
//fname := "C:\\Users\\huan\\AppData\\Roaming\\MetaQuotes\\Terminal\\1DAFD9A7C67DC84FE37EAA1FC1E5CF75\\history\\ICMarkets-Demo01\\00\\EURUSD30.hst"

f, err := os.OpenFile(fname, os.O_RDONLY, 666)
if err != nil {
Expand Down

0 comments on commit c5fb629

Please sign in to comment.