<commit_before>//  Copyright (c) 2018 Cisco and/or its affiliates.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

package app

import (
	"sync"

	"github.com/ligato/cn-infra/datasync"
	"github.com/ligato/cn-infra/datasync/kvdbsync"
	"github.com/ligato/cn-infra/datasync/kvdbsync/local"
	"github.com/ligato/cn-infra/datasync/msgsync"
	"github.com/ligato/cn-infra/datasync/resync"
	"github.com/ligato/cn-infra/db/keyval/consul"
	"github.com/ligato/cn-infra/db/keyval/etcd"
	"github.com/ligato/cn-infra/db/keyval/redis"
	"github.com/ligato/cn-infra/logging/logmanager"
	"github.com/ligato/cn-infra/messaging/kafka"
	"github.com/ligato/vpp-agent/plugins/linux"
	"github.com/ligato/vpp-agent/plugins/rest"
	"github.com/ligato/vpp-agent/plugins/telemetry"
	"github.com/ligato/vpp-agent/plugins/vpp"
	"github.com/ligato/vpp-agent/plugins/vpp/rpc"
)

// VPPAgent defines plugins which will be loaded and their order.
// Note: the plugin itself is loaded after all its dependencies. It means that the VPP plugin is first in the list
// despite it needs to be loaded after the linux plugin.
type VPPAgent struct {
	LogManager *logmanager.Plugin

	ETCDDataSync   *kvdbsync.Plugin
	ConsulDataSync *kvdbsync.Plugin
	RedisDataSync  *kvdbsync.Plugin

	VPP   *vpp.Plugin
	Linux *linux.Plugin

	GRPCService *rpc.Plugin
	RESTAPI     *rest.Plugin
	Telemetry   *telemetry.Plugin
}

func New() *VPPAgent {
	etcdDataSync := kvdbsync.NewPlugin(kvdbsync.UseKV(&etcd.DefaultPlugin))
	consulDataSync := kvdbsync.NewPlugin(kvdbsync.UseKV(&consul.DefaultPlugin))
	redisDataSync := kvdbsync.NewPlugin(kvdbsync.UseKV(&redis.DefaultPlugin))

	watcher := datasync.KVProtoWatchers{
		local.Get(),
		etcdDataSync,
		consulDataSync,
	}
	publisher := datasync.KVProtoWriters{
		etcdDataSync,
		consulDataSync,
	}

	ifStatePub := msgsync.NewPlugin(
		msgsync.UseMessaging(&kafka.DefaultPlugin),
		msgsync.UseConf(msgsync.Config{
			Topic: "if_state",
		}),
	)

	vppPlugin := vpp.NewPlugin(vpp.UseDeps(func(deps *vpp.Deps) {
		deps.Publish = publisher
		deps.Watcher = watcher
		deps.IfStatePub = ifStatePub
		deps.DataSyncs = map[string]datasync.KeyProtoValWriter{
			"etcd":  etcdDataSync,
			"redis": redisDataSync,
		}
		deps.GRPCSvc = &rpc.DefaultPlugin
	}))
	linuxPlugin := linux.NewPlugin(linux.UseDeps(func(deps *linux.Deps) {
		deps.VPP = vppPlugin
		deps.Watcher = watcher
	}))
	vppPlugin.Deps.Linux = linuxPlugin

	var watchEventsMutex sync.Mutex
	vppPlugin.Deps.WatchEventsMutex = &watchEventsMutex
	linuxPlugin.Deps.WatchEventsMutex = &watchEventsMutex

	restPlugin := rest.NewPlugin(rest.UseDeps(func(deps *rest.Deps) {
		deps.VPP = vppPlugin
	}))

	return &VPPAgent{
		LogManager:     &logmanager.DefaultPlugin,
		ETCDDataSync:   etcdDataSync,
		ConsulDataSync: consulDataSync,
		RedisDataSync:  redisDataSync,
		VPP:            vppPlugin,
		Linux:          linuxPlugin,
		GRPCService:    &rpc.DefaultPlugin,
		RESTAPI:        restPlugin,
		Telemetry:      &telemetry.DefaultPlugin,
	}
}
func (VPPAgent) Init() error {
	return nil
}

func (VPPAgent) AfterInit() error {
	// manually start resync after all plugins started
	resync.DefaultPlugin.DoResync()
	return nil
}

func (VPPAgent) Close() error {
	return nil
}

func (VPPAgent) String() string {
	return "VPPAgent"
}
<commit_msg>added probe plugin to enable liveness/readiness<commit_after>//  Copyright (c) 2018 Cisco and/or its affiliates.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

package app

import (
	"sync"

	"github.com/ligato/cn-infra/datasync"
	"github.com/ligato/cn-infra/datasync/kvdbsync"
	"github.com/ligato/cn-infra/datasync/kvdbsync/local"
	"github.com/ligato/cn-infra/datasync/msgsync"
	"github.com/ligato/cn-infra/datasync/resync"
	"github.com/ligato/cn-infra/db/keyval/consul"
	"github.com/ligato/cn-infra/db/keyval/etcd"
	"github.com/ligato/cn-infra/db/keyval/redis"
	"github.com/ligato/cn-infra/health/probe"
	"github.com/ligato/cn-infra/logging/logmanager"
	"github.com/ligato/cn-infra/messaging/kafka"
	"github.com/ligato/vpp-agent/plugins/linux"
	"github.com/ligato/vpp-agent/plugins/rest"
	"github.com/ligato/vpp-agent/plugins/telemetry"
	"github.com/ligato/vpp-agent/plugins/vpp"
	"github.com/ligato/vpp-agent/plugins/vpp/rpc"
)

// VPPAgent defines plugins which will be loaded and their order.
// Note: the plugin itself is loaded after all its dependencies. It means that the VPP plugin is first in the list
// despite it needs to be loaded after the linux plugin.
type VPPAgent struct {
	LogManager *logmanager.Plugin

	ETCDDataSync   *kvdbsync.Plugin
	ConsulDataSync *kvdbsync.Plugin
	RedisDataSync  *kvdbsync.Plugin

	VPP   *vpp.Plugin
	Linux *linux.Plugin

	GRPCService *rpc.Plugin
	RESTAPI     *rest.Plugin
	Probe       *probe.Plugin
	Telemetry   *telemetry.Plugin
}

func New() *VPPAgent {
	etcdDataSync := kvdbsync.NewPlugin(kvdbsync.UseKV(&etcd.DefaultPlugin))
	consulDataSync := kvdbsync.NewPlugin(kvdbsync.UseKV(&consul.DefaultPlugin))
	redisDataSync := kvdbsync.NewPlugin(kvdbsync.UseKV(&redis.DefaultPlugin))

	watcher := datasync.KVProtoWatchers{
		local.Get(),
		etcdDataSync,
		consulDataSync,
	}
	publisher := datasync.KVProtoWriters{
		etcdDataSync,
		consulDataSync,
	}

	ifStatePub := msgsync.NewPlugin(
		msgsync.UseMessaging(&kafka.DefaultPlugin),
		msgsync.UseConf(msgsync.Config{
			Topic: "if_state",
		}),
	)

	vppPlugin := vpp.NewPlugin(vpp.UseDeps(func(deps *vpp.Deps) {
		deps.Publish = publisher
		deps.Watcher = watcher
		deps.IfStatePub = ifStatePub
		deps.DataSyncs = map[string]datasync.KeyProtoValWriter{
			"etcd":  etcdDataSync,
			"redis": redisDataSync,
		}
		deps.GRPCSvc = &rpc.DefaultPlugin
	}))
	linuxPlugin := linux.NewPlugin(linux.UseDeps(func(deps *linux.Deps) {
		deps.VPP = vppPlugin
		deps.Watcher = watcher
	}))
	vppPlugin.Deps.Linux = linuxPlugin

	var watchEventsMutex sync.Mutex
	vppPlugin.Deps.WatchEventsMutex = &watchEventsMutex
	linuxPlugin.Deps.WatchEventsMutex = &watchEventsMutex

	restPlugin := rest.NewPlugin(rest.UseDeps(func(deps *rest.Deps) {
		deps.VPP = vppPlugin
	}))

	return &VPPAgent{
		LogManager:     &logmanager.DefaultPlugin,
		ETCDDataSync:   etcdDataSync,
		ConsulDataSync: consulDataSync,
		RedisDataSync:  redisDataSync,
		VPP:            vppPlugin,
		Linux:          linuxPlugin,
		GRPCService:    &rpc.DefaultPlugin,
		RESTAPI:        restPlugin,
		Probe:          &probe.DefaultPlugin,
		Telemetry:      &telemetry.DefaultPlugin,
	}
}
func (VPPAgent) Init() error {
	return nil
}

func (VPPAgent) AfterInit() error {
	// manually start resync after all plugins started
	resync.DefaultPlugin.DoResync()
	return nil
}

func (VPPAgent) Close() error {
	return nil
}

func (VPPAgent) String() string {
	return "VPPAgent"
}
<|endoftext|>


<commit_before>// Package bip39 is the official Golang implementation of the BIP39 spec.
//
// The official BIP39 spec can be found at
// https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
package bip39

import (
	"crypto/rand"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/binary"
	"errors"
	"fmt"
	"math/big"
	"strings"

	"github.com/tyler-smith/go-bip39/wordlists"
	"golang.org/x/crypto/pbkdf2"
)

var (
	// Some bitwise operands for working with big.Ints
	last11BitsMask          = big.NewInt(2047)
	rightShift11BitsDivider = big.NewInt(2048)
	bigOne                  = big.NewInt(1)
	bigTwo                  = big.NewInt(2)

	// used to isolate the checksum bits from the entropy+checksum byte array
	wordLengthChecksumMasksMapping = map[int]*big.Int{
		12: big.NewInt(15),
		15: big.NewInt(31),
		18: big.NewInt(63),
		21: big.NewInt(127),
		24: big.NewInt(255),
	}
	// used to use only the desired x of 8 available checksum bits.
	// 256 bit (word length 24) requires all 8 bits of the checksum,
	// and thus no shifting is needed for it (we would get a divByZero crash if we did)
	wordLengthChecksumShiftMapping = map[int]*big.Int{
		12: big.NewInt(16),
		15: big.NewInt(8),
		18: big.NewInt(4),
		21: big.NewInt(2),
	}

	// wordList is the set of words to use
	wordList []string

	// wordMap is a reverse lookup map for wordList
	wordMap map[string]int
)

var (
	// ErrInvalidMnemonic is returned when trying to use a malformed mnemonic.
	ErrInvalidMnemonic = errors.New("Invalid menomic")

	// ErrEntropyLengthInvalid is returned when trying to use an entropy set with
	// an invalid size.
	ErrEntropyLengthInvalid = errors.New("Entropy length must be [128, 256] and a multiple of 32")

	// ErrValidatedSeedLengthMismatch is returned when a validated seed is not the
	// same size as the given seed. This should never happen is present only as a
	// sanity assertion.
	ErrValidatedSeedLengthMismatch = errors.New("Seed length does not match validated seed length")

	// ErrChecksumIncorrect is returned when entropy has the incorrect checksum.
	ErrChecksumIncorrect = errors.New("Checksum incorrect")
)

func init() {
	SetWordList(wordlists.English)
}

// SetWordList sets the list of words to use for mnemonics. Currently the list
// that is set is used package-wide.
func SetWordList(list []string) {
	wordList = list
	wordMap = map[string]int{}
	for i, v := range wordList {
		wordMap[v] = i
	}
}

// NewEntropy will create random entropy bytes
// so long as the requested size bitSize is an appropriate size.
//
// bitSize has to be a multiple 32 and be within the inclusive range of {128, 256}
func NewEntropy(bitSize int) ([]byte, error) {
	err := validateEntropyBitSize(bitSize)
	if err != nil {
		return nil, err
	}

	entropy := make([]byte, bitSize/8)
	_, err = rand.Read(entropy)
	return entropy, err
}

// EntropyFromMnemonic takes a mnemonic generated by this library,
// and returns the input entropy used to generate the given mnemonic.
// An error is returned if the given mnemonic is invalid.
func EntropyFromMnemonic(mnemonic string) ([]byte, error) {
	mnemonicSlice, isValid := splitMnemonicWords(mnemonic)
	if !isValid {
		return nil, errors.New("Invalid mnemonic")
	}

	b := big.NewInt(0)
	for _, v := range mnemonicSlice {
		index, found := wordMap[v]
		if found == false {
			return nil, fmt.Errorf("word `%v` not found in reverse map", v)
		}
		var wordBytes [2]byte
		binary.BigEndian.PutUint16(wordBytes[:], uint16(index))
		b = b.Mul(b, rightShift11BitsDivider)
		b = b.Or(b, big.NewInt(0).SetBytes(wordBytes[:]))
	}

	checksum := big.NewInt(0)
	checksumMask := wordLengthChecksumMasksMapping[len(mnemonicSlice)]
	checksum = checksum.And(b, checksumMask)

	b.Div(b, big.NewInt(0).Add(checksumMask, bigOne))
	entropy := b.Bytes()
	// pad entropy if needed
	entropy = padByteSlice(entropy, len(mnemonicSlice)/3*4)

	// generate the checksum once again, mask and ensure it equals the checksum we got from the mneomnic
	entropyChecksumBytes := computeChecksum(entropy)
	entropyChecksum := big.NewInt(int64(entropyChecksumBytes[0]))
	if l := len(mnemonicSlice); l != 24 {
		checksumShift := wordLengthChecksumShiftMapping[l]
		entropyChecksum.Div(entropyChecksum, checksumShift)
	}

	if checksum.Cmp(entropyChecksum) != 0 {
		return nil, errors.New("mnemonic's entropy doesn't match its checksum")
	}

	// return (padded) entropy
	return entropy, nil
}

// NewMnemonic will return a string consisting of the mnemonic words for
// the given entropy.
// If the provide entropy is invalid, an error will be returned.
func NewMnemonic(entropy []byte) (string, error) {
	// Compute some lengths for convenience
	entropyBitLength := len(entropy) * 8
	checksumBitLength := entropyBitLength / 32
	sentenceLength := (entropyBitLength + checksumBitLength) / 11

	err := validateEntropyBitSize(entropyBitLength)
	if err != nil {
		return "", err
	}

	// Add checksum to entropy
	entropy = addChecksum(entropy)

	// Break entropy up into sentenceLength chunks of 11 bits
	// For each word AND mask the rightmost 11 bits and find the word at that index
	// Then bitshift entropy 11 bits right and repeat
	// Add to the last empty slot so we can work with LSBs instead of MSB

	// Entropy as an int so we can bitmask without worrying about bytes slices
	entropyInt := new(big.Int).SetBytes(entropy)

	// Slice to hold words in
	words := make([]string, sentenceLength)

	// Throw away big int for AND masking
	word := big.NewInt(0)

	for i := sentenceLength - 1; i >= 0; i-- {
		// Get 11 right most bits and bitshift 11 to the right for next time
		word.And(entropyInt, last11BitsMask)
		entropyInt.Div(entropyInt, rightShift11BitsDivider)

		// Get the bytes representing the 11 bits as a 2 byte slice
		wordBytes := padByteSlice(word.Bytes(), 2)

		// Convert bytes to an index and add that word to the list
		words[i] = wordList[binary.BigEndian.Uint16(wordBytes)]
	}

	return strings.Join(words, " "), nil
}

// MnemonicToByteArray takes a mnemonic string and turns it into a byte array
// suitable for creating another mnemonic.
// An error is returned if the mnemonic is invalid.
func MnemonicToByteArray(mnemonic string, raw ...bool) ([]byte, error) {
	var (
		mnemonicSlice    = strings.Split(mnemonic, " ")
		entropyBitSize   = len(mnemonicSlice) * 11
		checksumBitSize  = entropyBitSize % 32
		fullByteSize     = (entropyBitSize-checksumBitSize)/8 + 1
		checksumByteSize = fullByteSize - (fullByteSize % 4)
	)

	// Pre validate that the mnemonic is well formed and only contains words that
	// are present in the word list
	if !IsMnemonicValid(mnemonic) {
		return nil, ErrInvalidMnemonic
	}

	// Convert word indices to a `big.Int` representing the entropy
	checksummedEntropy := big.NewInt(0)
	modulo := big.NewInt(2048)
	for _, v := range mnemonicSlice {
		index := big.NewInt(int64(wordMap[v]))
		checksummedEntropy.Mul(checksummedEntropy, modulo)
		checksummedEntropy.Add(checksummedEntropy, index)
	}

	// Calculate the unchecksummed entropy so we can validate that the checksum is
	// correct
	checksumModulo := big.NewInt(0).Exp(bigTwo, big.NewInt(int64(checksumBitSize)), nil)
	rawEntropy := big.NewInt(0).Div(checksummedEntropy, checksumModulo)

	// Convert `big.Int`s to byte padded byte slices
	rawEntropyBytes := padByteSlice(rawEntropy.Bytes(), checksumByteSize)
	checksummedEntropyBytes := padByteSlice(checksummedEntropy.Bytes(), fullByteSize)

	// Validate that the checksum is correct
	newChecksummedEntropyBytes := padByteSlice(addChecksum(rawEntropyBytes), fullByteSize)
	if !compareByteSlices(checksummedEntropyBytes, newChecksummedEntropyBytes) {
		return nil, ErrChecksumIncorrect
	}

	if raw == nil {
		return checksummedEntropyBytes, nil
	}
	if raw[0] == true {
		return rawEntropyBytes, nil
	}
	return checksummedEntropyBytes, nil
}

// NewSeedWithErrorChecking creates a hashed seed output given the mnemonic string and a password.
// An error is returned if the mnemonic is not convertible to a byte array.
func NewSeedWithErrorChecking(mnemonic string, password string) ([]byte, error) {
	_, err := MnemonicToByteArray(mnemonic)
	if err != nil {
		return nil, err
	}
	return NewSeed(mnemonic, password), nil
}

// NewSeed creates a hashed seed output given a provided string and password.
// No checking is performed to validate that the string provided is a valid mnemonic.
func NewSeed(mnemonic string, password string) []byte {
	return pbkdf2.Key([]byte(mnemonic), []byte("mnemonic"+password), 2048, 64, sha512.New)
}

// IsMnemonicValid attempts to verify that the provided mnemonic is valid.
// Validity is determined by both the number of words being appropriate,
// and that all the words in the mnemonic are present in the word list.
func IsMnemonicValid(mnemonic string) bool {
	// Create a list of all the words in the mnemonic sentence
	words := strings.Fields(mnemonic)

	// Get word count
	wordCount := len(words)

	// The number of words should be 12, 15, 18, 21 or 24
	if wordCount%3 != 0 || wordCount < 12 || wordCount > 24 {
		return false
	}

	// Check if all words belong in the wordlist
	for _, word := range words {
		if _, ok := wordMap[word]; !ok {
			return false
		}
	}

	return true
}

// Appends to data the first (len(data) / 32)bits of the result of sha256(data)
// Currently only supports data up to 32 bytes
func addChecksum(data []byte) []byte {
	// Get first byte of sha256
	hash := computeChecksum(data)
	firstChecksumByte := hash[0]

	// len() is in bytes so we divide by 4
	checksumBitLength := uint(len(data) / 4)

	// For each bit of check sum we want we shift the data one the left
	// and then set the (new) right most bit equal to checksum bit at that index
	// staring from the left
	dataBigInt := new(big.Int).SetBytes(data)
	for i := uint(0); i < checksumBitLength; i++ {
		// Bitshift 1 left
		dataBigInt.Mul(dataBigInt, bigTwo)

		// Set rightmost bit if leftmost checksum bit is set
		if uint8(firstChecksumByte&(1<<(7-i))) > 0 {
			dataBigInt.Or(dataBigInt, bigOne)
		}
	}

	return dataBigInt.Bytes()
}

func computeChecksum(data []byte) []byte {
	hasher := sha256.New()
	hasher.Write(data)
	return hasher.Sum(nil)
}

// validateEntropyBitSize ensures that entropy is the correct size for being a
// mnemonic.
func validateEntropyBitSize(bitSize int) error {
	if (bitSize%32) != 0 || bitSize < 128 || bitSize > 256 {
		return ErrEntropyLengthInvalid
	}
	return nil
}

// padByteSlice returns a byte slice of the given size with contents of the
// given slice left padded and any empty spaces filled with 0's.
func padByteSlice(slice []byte, length int) []byte {
	offset := length - len(slice)
	if offset <= 0 {
		return slice
	}
	newSlice := make([]byte, length)
	copy(newSlice[offset:], slice)
	return newSlice
}

// compareByteSlices returns true of the byte slices have equal contents and
// returns false otherwise.
func compareByteSlices(a, b []byte) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

func splitMnemonicWords(mnemonic string) ([]string, bool) {
	// Create a list of all the words in the mnemonic sentence
	words := strings.Fields(mnemonic)

	//Get num of words
	numOfWords := len(words)

	// The number of words should be 12, 15, 18, 21 or 24
	if numOfWords%3 != 0 || numOfWords < 12 || numOfWords > 24 {
		return nil, false
	}
	return words, true
}
<commit_msg>Implement method get current list word use for mnemonics<commit_after>// Package bip39 is the official Golang implementation of the BIP39 spec.
//
// The official BIP39 spec can be found at
// https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
package bip39

import (
	"crypto/rand"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/binary"
	"errors"
	"fmt"
	"math/big"
	"strings"

	"github.com/tyler-smith/go-bip39/wordlists"
	"golang.org/x/crypto/pbkdf2"
)

var (
	// Some bitwise operands for working with big.Ints
	last11BitsMask          = big.NewInt(2047)
	rightShift11BitsDivider = big.NewInt(2048)
	bigOne                  = big.NewInt(1)
	bigTwo                  = big.NewInt(2)

	// used to isolate the checksum bits from the entropy+checksum byte array
	wordLengthChecksumMasksMapping = map[int]*big.Int{
		12: big.NewInt(15),
		15: big.NewInt(31),
		18: big.NewInt(63),
		21: big.NewInt(127),
		24: big.NewInt(255),
	}
	// used to use only the desired x of 8 available checksum bits.
	// 256 bit (word length 24) requires all 8 bits of the checksum,
	// and thus no shifting is needed for it (we would get a divByZero crash if we did)
	wordLengthChecksumShiftMapping = map[int]*big.Int{
		12: big.NewInt(16),
		15: big.NewInt(8),
		18: big.NewInt(4),
		21: big.NewInt(2),
	}

	// wordList is the set of words to use
	wordList []string

	// wordMap is a reverse lookup map for wordList
	wordMap map[string]int
)

var (
	// ErrInvalidMnemonic is returned when trying to use a malformed mnemonic.
	ErrInvalidMnemonic = errors.New("Invalid menomic")

	// ErrEntropyLengthInvalid is returned when trying to use an entropy set with
	// an invalid size.
	ErrEntropyLengthInvalid = errors.New("Entropy length must be [128, 256] and a multiple of 32")

	// ErrValidatedSeedLengthMismatch is returned when a validated seed is not the
	// same size as the given seed. This should never happen is present only as a
	// sanity assertion.
	ErrValidatedSeedLengthMismatch = errors.New("Seed length does not match validated seed length")

	// ErrChecksumIncorrect is returned when entropy has the incorrect checksum.
	ErrChecksumIncorrect = errors.New("Checksum incorrect")
)

func init() {
	SetWordList(wordlists.English)
}

// SetWordList sets the list of words to use for mnemonics. Currently the list
// that is set is used package-wide.
func SetWordList(list []string) {
	wordList = list
	wordMap = map[string]int{}
	for i, v := range wordList {
		wordMap[v] = i
	}
}

// GetWordList gets the list of words to use for mnemonics
func GetWordList() []string {
	return wordList
}

// NewEntropy will create random entropy bytes
// so long as the requested size bitSize is an appropriate size.
//
// bitSize has to be a multiple 32 and be within the inclusive range of {128, 256}
func NewEntropy(bitSize int) ([]byte, error) {
	err := validateEntropyBitSize(bitSize)
	if err != nil {
		return nil, err
	}

	entropy := make([]byte, bitSize/8)
	_, err = rand.Read(entropy)
	return entropy, err
}

// EntropyFromMnemonic takes a mnemonic generated by this library,
// and returns the input entropy used to generate the given mnemonic.
// An error is returned if the given mnemonic is invalid.
func EntropyFromMnemonic(mnemonic string) ([]byte, error) {
	mnemonicSlice, isValid := splitMnemonicWords(mnemonic)
	if !isValid {
		return nil, errors.New("Invalid mnemonic")
	}

	b := big.NewInt(0)
	for _, v := range mnemonicSlice {
		index, found := wordMap[v]
		if found == false {
			return nil, fmt.Errorf("word `%v` not found in reverse map", v)
		}
		var wordBytes [2]byte
		binary.BigEndian.PutUint16(wordBytes[:], uint16(index))
		b = b.Mul(b, rightShift11BitsDivider)
		b = b.Or(b, big.NewInt(0).SetBytes(wordBytes[:]))
	}

	checksum := big.NewInt(0)
	checksumMask := wordLengthChecksumMasksMapping[len(mnemonicSlice)]
	checksum = checksum.And(b, checksumMask)

	b.Div(b, big.NewInt(0).Add(checksumMask, bigOne))
	entropy := b.Bytes()
	// pad entropy if needed
	entropy = padByteSlice(entropy, len(mnemonicSlice)/3*4)

	// generate the checksum once again, mask and ensure it equals the checksum we got from the mneomnic
	entropyChecksumBytes := computeChecksum(entropy)
	entropyChecksum := big.NewInt(int64(entropyChecksumBytes[0]))
	if l := len(mnemonicSlice); l != 24 {
		checksumShift := wordLengthChecksumShiftMapping[l]
		entropyChecksum.Div(entropyChecksum, checksumShift)
	}

	if checksum.Cmp(entropyChecksum) != 0 {
		return nil, errors.New("mnemonic's entropy doesn't match its checksum")
	}

	// return (padded) entropy
	return entropy, nil
}

// NewMnemonic will return a string consisting of the mnemonic words for
// the given entropy.
// If the provide entropy is invalid, an error will be returned.
func NewMnemonic(entropy []byte) (string, error) {
	// Compute some lengths for convenience
	entropyBitLength := len(entropy) * 8
	checksumBitLength := entropyBitLength / 32
	sentenceLength := (entropyBitLength + checksumBitLength) / 11

	err := validateEntropyBitSize(entropyBitLength)
	if err != nil {
		return "", err
	}

	// Add checksum to entropy
	entropy = addChecksum(entropy)

	// Break entropy up into sentenceLength chunks of 11 bits
	// For each word AND mask the rightmost 11 bits and find the word at that index
	// Then bitshift entropy 11 bits right and repeat
	// Add to the last empty slot so we can work with LSBs instead of MSB

	// Entropy as an int so we can bitmask without worrying about bytes slices
	entropyInt := new(big.Int).SetBytes(entropy)

	// Slice to hold words in
	words := make([]string, sentenceLength)

	// Throw away big int for AND masking
	word := big.NewInt(0)

	for i := sentenceLength - 1; i >= 0; i-- {
		// Get 11 right most bits and bitshift 11 to the right for next time
		word.And(entropyInt, last11BitsMask)
		entropyInt.Div(entropyInt, rightShift11BitsDivider)

		// Get the bytes representing the 11 bits as a 2 byte slice
		wordBytes := padByteSlice(word.Bytes(), 2)

		// Convert bytes to an index and add that word to the list
		words[i] = wordList[binary.BigEndian.Uint16(wordBytes)]
	}

	return strings.Join(words, " "), nil
}

// MnemonicToByteArray takes a mnemonic string and turns it into a byte array
// suitable for creating another mnemonic.
// An error is returned if the mnemonic is invalid.
func MnemonicToByteArray(mnemonic string, raw ...bool) ([]byte, error) {
	var (
		mnemonicSlice    = strings.Split(mnemonic, " ")
		entropyBitSize   = len(mnemonicSlice) * 11
		checksumBitSize  = entropyBitSize % 32
		fullByteSize     = (entropyBitSize-checksumBitSize)/8 + 1
		checksumByteSize = fullByteSize - (fullByteSize % 4)
	)

	// Pre validate that the mnemonic is well formed and only contains words that
	// are present in the word list
	if !IsMnemonicValid(mnemonic) {
		return nil, ErrInvalidMnemonic
	}

	// Convert word indices to a `big.Int` representing the entropy
	checksummedEntropy := big.NewInt(0)
	modulo := big.NewInt(2048)
	for _, v := range mnemonicSlice {
		index := big.NewInt(int64(wordMap[v]))
		checksummedEntropy.Mul(checksummedEntropy, modulo)
		checksummedEntropy.Add(checksummedEntropy, index)
	}

	// Calculate the unchecksummed entropy so we can validate that the checksum is
	// correct
	checksumModulo := big.NewInt(0).Exp(bigTwo, big.NewInt(int64(checksumBitSize)), nil)
	rawEntropy := big.NewInt(0).Div(checksummedEntropy, checksumModulo)

	// Convert `big.Int`s to byte padded byte slices
	rawEntropyBytes := padByteSlice(rawEntropy.Bytes(), checksumByteSize)
	checksummedEntropyBytes := padByteSlice(checksummedEntropy.Bytes(), fullByteSize)

	// Validate that the checksum is correct
	newChecksummedEntropyBytes := padByteSlice(addChecksum(rawEntropyBytes), fullByteSize)
	if !compareByteSlices(checksummedEntropyBytes, newChecksummedEntropyBytes) {
		return nil, ErrChecksumIncorrect
	}

	if raw == nil {
		return checksummedEntropyBytes, nil
	}
	if raw[0] == true {
		return rawEntropyBytes, nil
	}
	return checksummedEntropyBytes, nil
}

// NewSeedWithErrorChecking creates a hashed seed output given the mnemonic string and a password.
// An error is returned if the mnemonic is not convertible to a byte array.
func NewSeedWithErrorChecking(mnemonic string, password string) ([]byte, error) {
	_, err := MnemonicToByteArray(mnemonic)
	if err != nil {
		return nil, err
	}
	return NewSeed(mnemonic, password), nil
}

// NewSeed creates a hashed seed output given a provided string and password.
// No checking is performed to validate that the string provided is a valid mnemonic.
func NewSeed(mnemonic string, password string) []byte {
	return pbkdf2.Key([]byte(mnemonic), []byte("mnemonic"+password), 2048, 64, sha512.New)
}

// IsMnemonicValid attempts to verify that the provided mnemonic is valid.
// Validity is determined by both the number of words being appropriate,
// and that all the words in the mnemonic are present in the word list.
func IsMnemonicValid(mnemonic string) bool {
	// Create a list of all the words in the mnemonic sentence
	words := strings.Fields(mnemonic)

	// Get word count
	wordCount := len(words)

	// The number of words should be 12, 15, 18, 21 or 24
	if wordCount%3 != 0 || wordCount < 12 || wordCount > 24 {
		return false
	}

	// Check if all words belong in the wordlist
	for _, word := range words {
		if _, ok := wordMap[word]; !ok {
			return false
		}
	}

	return true
}

// Appends to data the first (len(data) / 32)bits of the result of sha256(data)
// Currently only supports data up to 32 bytes
func addChecksum(data []byte) []byte {
	// Get first byte of sha256
	hash := computeChecksum(data)
	firstChecksumByte := hash[0]

	// len() is in bytes so we divide by 4
	checksumBitLength := uint(len(data) / 4)

	// For each bit of check sum we want we shift the data one the left
	// and then set the (new) right most bit equal to checksum bit at that index
	// staring from the left
	dataBigInt := new(big.Int).SetBytes(data)
	for i := uint(0); i < checksumBitLength; i++ {
		// Bitshift 1 left
		dataBigInt.Mul(dataBigInt, bigTwo)

		// Set rightmost bit if leftmost checksum bit is set
		if uint8(firstChecksumByte&(1<<(7-i))) > 0 {
			dataBigInt.Or(dataBigInt, bigOne)
		}
	}

	return dataBigInt.Bytes()
}

func computeChecksum(data []byte) []byte {
	hasher := sha256.New()
	hasher.Write(data)
	return hasher.Sum(nil)
}

// validateEntropyBitSize ensures that entropy is the correct size for being a
// mnemonic.
func validateEntropyBitSize(bitSize int) error {
	if (bitSize%32) != 0 || bitSize < 128 || bitSize > 256 {
		return ErrEntropyLengthInvalid
	}
	return nil
}

// padByteSlice returns a byte slice of the given size with contents of the
// given slice left padded and any empty spaces filled with 0's.
func padByteSlice(slice []byte, length int) []byte {
	offset := length - len(slice)
	if offset <= 0 {
		return slice
	}
	newSlice := make([]byte, length)
	copy(newSlice[offset:], slice)
	return newSlice
}

// compareByteSlices returns true of the byte slices have equal contents and
// returns false otherwise.
func compareByteSlices(a, b []byte) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

func splitMnemonicWords(mnemonic string) ([]string, bool) {
	// Create a list of all the words in the mnemonic sentence
	words := strings.Fields(mnemonic)

	// Get num of words
	numOfWords := len(words)

	// The number of words should be 12, 15, 18, 21 or 24
	if numOfWords%3 != 0 || numOfWords < 12 || numOfWords > 24 {
		return nil, false
	}
	return words, true
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"strconv"
	"time"
)

func main() {

	var num int64
	var target []string
	var lang string

	if len(os.Args) > 3 {
		num, _ = strconv.ParseInt(os.Args[1], 10, 64)
		lang = os.Args[2]
		target = os.Args[3:]
	} else {
		log.Fatal("number of iterations, lang, target program")
	}

	var i int64 // XXX

	start := time.Now()

	for i = 0; i < num; i++ {

		fmt.Printf("%d ", i)

		out, err := exec.Command(lang, target...).Output()

		if i == 0 {
			fmt.Fprintf(os.Stderr, "%s\n", out)
		}

		if err != nil {
			log.Fatal(err)
		}

	}

	elapsed := time.Since(start).Seconds()
	avg := elapsed / float64(num)
	fmt.Printf("\n\"%s %s\" %d run(s) wallclock=%0.2f avg=%0.2f sec(s)\n", lang, target, num, float64(elapsed), avg)

}
<commit_msg>better output<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"
)

func main() {

	var num int64
	var target []string
	var lang string

	if len(os.Args) > 3 {
		num, _ = strconv.ParseInt(os.Args[1], 10, 64)
		lang = os.Args[2]
		target = os.Args[3:]
	} else {
		log.Fatal("number of iterations, lang, target program")
	}

	var i int64 // XXX

	start := time.Now()

	for i = 0; i < num; i++ {

		fmt.Printf("%d ", i)

		out, err := exec.Command(lang, target...).Output()

		if i == 0 {
			fmt.Fprintf(os.Stderr, "%s\n", out)
		}

		if err != nil {
			log.Fatal(err)
		}

	}

	elapsed := time.Since(start).Seconds()
	avg := elapsed / float64(num)
	fmt.Printf("\n\"%s %s\" %d run(s) wallclock=%0.2f avg=%0.2f sec(s)\n", lang, strings.Join(target, ""), num, float64(elapsed), avg)

}
<|endoftext|>


<commit_before>package async

import (
	"bytes"
	"fmt"
	"reflect"
	"runtime"
	"strings"
)

var (
	emptyStr    string
	emptyError  error
	emptyResult []interface{}
	emptyArgs   []reflect.Value
)

// Errors is a type of []error
// This is used to pass multiple errors when using parallel or concurrent methods
// and yet subscribe to the error interface
type Errors []error

func (e Errors) Error() string {
	buff := bytes.NewBufferString(emptyStr)

	for _, err := range e {
		buff.WriteString(err.Error())
		buff.WriteString(" ")
	}

	return strings.TrimSpace(buff.String())
}

// Type used as a list of tasks
type Tasks []interface{}

// funcs is the struct used to control the stack
// of functions to be executed.
type tasks struct {
	Stack []reflect.Value
}

// ExecInSeries executes recursively each task of the stack until it reachs
// the bottom of the stack or it is interrupted by an error
func (t *tasks) ExecInSeries(args ...reflect.Value) ([]interface{}, error) {
	var (
		// true if function has the last return value is of type `error`
		returnsError bool
		// Get function to be executed
		fn reflect.Value
		// Get type of the function to be executed
		fnt reflect.Type
		// Parameters to be sent to the next function
		outArgs []reflect.Value
	)

	// end of stack, no need to proceed
	if len(t.Stack) == 0 {
		result := emptyResult
		if l := len(args); l > 0 {
			for i := 0; i < l; i++ {
				result = append(result, args[i].Interface())
			}
		}
		return result, nil
	}

	// Get function to be executed
	fn = t.Stack[0]
	// Get type of the function to be executed
	fnt = fn.Type()

	// If function expect any argument
	if l := fnt.NumOut(); l > 0 {
		// Get last argument of the function
		lastArg := fnt.Out(l - 1)

		// Check if the last argument is a error
		returnsError = reflect.Zero(lastArg).Interface() == emptyError
	}

	// Remove current function from the stack
	t.Stack = t.Stack[1:len(t.Stack)]

	outArgs = fn.Call(args)

	lr := len(outArgs)

	// If function is expecting an `error`
	if lr > 0 && returnsError {
		// check if the error occured, if so returns the error and break the execution
		if e, ok := outArgs[lr-1].Interface().(error); ok {
			return emptyResult, e
		}
		lr = lr - 1
	}
	return t.ExecInSeries(outArgs[:lr]...)
}

// ExecInParallel executes all functions in the stack in Parallel.
func (t *tasks) ExecInParallel() error {
	var (
		errs Errors
		// Length of the tasks to execute
		ls = len(t.Stack)
		// Creates buffered channel for errors
		ce = make(chan error, ls)
		// Creates bufferd channel for controlling limit of CPU usage
		climit = make(chan int, runtime.GOMAXPROCS(0))
	)

	for i := 0; i < ls; i++ {
		climit <- 1
		go execRoutine(t.Stack[i], ce)
		<-climit // discards the message, make space in buffer
	}

	// Consumes the errors from the channel
	for i := 0; i < ls; i++ {
		if e := <-ce; e != nil {
			errs = append(errs, e)
		}
	}

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

	return errs
}

func execRoutine(f reflect.Value, c chan error) {
	var (
		resErr error
		res    = f.Call(emptyArgs)
	)

	// Check if an error occurred
	if lr := len(res); lr > 0 {
		if e, ok := res[lr-1].Interface().(error); ok {
			resErr = e
		}
	}
	// Sends message to the channel
	c <- resErr
}

// Waterfall executes every task sequencially.
// The execution flow may be interrupted by returning an error.
// `firstArgs` is a slice of parameters to be passed to the first task of the stack.
func Waterfall(stack Tasks, firstArgs ...interface{}) ([]interface{}, error) {
	var (
		err  error
		args []reflect.Value
		t    = &tasks{}
	)
	// Checks if the Tasks passed are valid functions.
	t.Stack, err = validFuncs(stack)

	if err != nil {
		return emptyResult, err
	}

	// transform interface{} to reflect.Value for execution
	for i := 0; i < len(firstArgs); i++ {
		args = append(args, reflect.ValueOf(firstArgs[i]))
	}

	return t.ExecInSeries(args...)
}

func Parallel(stack Tasks) error {
	var (
		err error
		t   *tasks = &tasks{}
	)

	// Checks if the Tasks passed are valid functions.
	t.Stack, err = validFuncs(stack)

	if err != nil {
		return err
	}
	return t.ExecInParallel()
}

// Loop through the stack of Tasks and check if they are valid functions.
// Returns the functions as []reflect.Value and error
func validFuncs(stack Tasks) ([]reflect.Value, error) {
	var rf []reflect.Value
	// Checks if arguments passed are valid functions.
	for i := 0; i < len(stack); i++ {
		v := reflect.Indirect(reflect.ValueOf(stack[i]))

		if v.Kind() != reflect.Func {
			return rf, fmt.Errorf("%T must be a Function ", v)
		}

		rf = append(rf, v)
	}
	return rf, nil
}
<commit_msg>Added paralellism.<commit_after>package async

import (
	"bytes"
	"fmt"
	"reflect"
	"runtime"
	"strings"
)

var (
	emptyStr    string
	emptyError  error
	emptyResult []interface{}
	emptyArgs   []reflect.Value
)

// Errors is a type of []error
// This is used to pass multiple errors when using parallel or concurrent methods
// and yet subscribe to the error interface
type Errors []error

func (e Errors) Error() string {
	b := bytes.NewBufferString(emptyStr)

	for _, err := range e {
		b.WriteString(err.Error())
		b.WriteString(" ")
	}

	return strings.TrimSpace(b.String())
}

// Type used as a list of tasks
type Tasks []interface{}

// funcs is the struct used to control the stack
// of functions to be executed.
type tasks struct {
	Stack []reflect.Value
}

// ExecInSeries executes recursively each task of the stack until it reachs
// the bottom of the stack or it is interrupted by an error
func (t *tasks) ExecInSeries(args ...reflect.Value) ([]interface{}, error) {
	var (
		// true if function has the last return value is of type `error`
		returnsError bool
		// Get function to be executed
		fn reflect.Value
		// Get type of the function to be executed
		fnt reflect.Type
		// Parameters to be sent to the next function
		outArgs []reflect.Value
	)

	// end of stack, no need to proceed
	if len(t.Stack) == 0 {
		result := emptyResult
		if l := len(args); l > 0 {
			for i := 0; i < l; i++ {
				result = append(result, args[i].Interface())
			}
		}
		return result, nil
	}

	// Get function to be executed
	fn = t.Stack[0]
	// Get type of the function to be executed
	fnt = fn.Type()

	// If function expect any argument
	if l := fnt.NumOut(); l > 0 {
		// Get last argument of the function
		lastArg := fnt.Out(l - 1)

		// Check if the last argument is a error
		returnsError = reflect.Zero(lastArg).Interface() == emptyError
	}

	// Remove current function from the stack
	t.Stack = t.Stack[1:len(t.Stack)]

	outArgs = fn.Call(args)

	lr := len(outArgs)

	// If function is expecting an `error`
	if lr > 0 && returnsError {
		// check if the error occured, if so returns the error and break the execution
		if e, ok := outArgs[lr-1].Interface().(error); ok {
			return emptyResult, e
		}
		lr = lr - 1
	}
	return t.ExecInSeries(outArgs[:lr]...)
}

// ExecInParallel executes all functions in the stack in Parallel.
func (t *tasks) ExecInParallel() error {
	var (
		errs Errors
		// Length of the tasks to execute
		ls = len(t.Stack)
		// Creates buffered channel for errors
		ce = make(chan error, ls)
		// Creates bufferd channel for controlling CPU usage and guarantee Paralellism
		climit = make(chan int, runtime.GOMAXPROCS(0))
	)

	for i := 0; i < ls; i++ {
		climit <- 1
		go execRoutine(t.Stack[i], ce)
		<-climit // discards the message, make space in buffer
	}

	// Consumes the errors from the channel
	for i := 0; i < ls; i++ {
		if e := <-ce; e != nil {
			errs = append(errs, e)
		}
	}

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

	return errs
}

func execRoutine(f reflect.Value, c chan error) {
	var (
		resErr error
		res    = f.Call(emptyArgs)
	)

	// Check if an error occurred
	if lr := len(res); lr > 0 {
		if e, ok := res[lr-1].Interface().(error); ok {
			resErr = e
		}
	}
	// Sends message to the channel
	c <- resErr
}

// Waterfall executes every task sequencially.
// The execution flow may be interrupted by returning an error.
// `firstArgs` is a slice of parameters to be passed to the first task of the stack.
func Waterfall(stack Tasks, firstArgs ...interface{}) ([]interface{}, error) {
	var (
		err  error
		args []reflect.Value
		t    = &tasks{}
	)
	// Checks if the Tasks passed are valid functions.
	t.Stack, err = validFuncs(stack)

	if err != nil {
		return emptyResult, err
	}

	// transform interface{} to reflect.Value for execution
	for i := 0; i < len(firstArgs); i++ {
		args = append(args, reflect.ValueOf(firstArgs[i]))
	}

	return t.ExecInSeries(args...)
}

func Parallel(stack Tasks) error {
	var (
		err error
		t   *tasks = &tasks{}
	)

	// Checks if the Tasks passed are valid functions.
	t.Stack, err = validFuncs(stack)

	if err != nil {
		return err
	}
	return t.ExecInParallel()
}

// Loop through the stack of Tasks and check if they are valid functions.
// Returns the functions as []reflect.Value and error
func validFuncs(stack Tasks) ([]reflect.Value, error) {
	var rf []reflect.Value
	// Checks if arguments passed are valid functions.
	for i := 0; i < len(stack); i++ {
		v := reflect.Indirect(reflect.ValueOf(stack[i]))

		if v.Kind() != reflect.Func {
			return rf, fmt.Errorf("%T must be a Function ", v)
		}

		rf = append(rf, v)
	}
	return rf, nil
}
<|endoftext|>


<commit_before>package main

import (
	"bitmm/bitfinex"
	"fmt"
	"github.com/grd/stat"
	"log"
	"math"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"time"
)

// Trade inputs
const (
	SYMBOL    = "btcusd" // Instrument to trade
	MINCHANGE = 0.1      // Minumum change required to update prices
	TRADENUM  = 40       // Number of trades to use in calculations
	MINO      = 0.01     // Min order size
)

var (
	api        = bitfinex.New(os.Getenv("BITFINEX_KEY"), os.Getenv("BITFINEX_SECRET"))
	apiErrors  = false // Set to true on any error
	liveOrders = false // Set to true on any order
	orderTheo  = 0.0   // Theo value on which the live orders are based
	orderPos   = 0.0   // Position on which the live orders are based
	// Fed in as OS args:
	maxPos      float64 // Maximum Position size
	minEdge     float64 // Minimum edge for position entry
	stdMult     float64 // Multiplier for standard deviation
	exitPercent float64 // Percent of edge for position exit
)

func main() {
	if len(os.Args) < 5 {
		fmt.Printf("usage: %s <size> <minimum edge> <stdev multiplier> <exit percent edge>\n",
			filepath.Base(os.Args[0]))
		os.Exit(1)
	}

	fmt.Println("\nInitializing...")

	// Set file for logging
	logFile, err := os.OpenFile("bitmm_log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatal(err)
	}
	defer logFile.Close()
	log.SetOutput(logFile)

	// Get maxPos, minEdge, exitPercent from user input
	getArgs()

	// Check for input to break loop
	inputChan := make(chan rune)
	go checkStdin(inputChan)

	// Run loop until user input is received
	runMainLoop(inputChan)
}

func getArgs() {
	var err error
	if maxPos, err = strconv.ParseFloat(os.Args[1], 64); err != nil {
		log.Fatal(err)
	}
	if minEdge, err = strconv.ParseFloat(os.Args[2], 64); err != nil {
		log.Fatal(err)
	}
	if stdMult, err = strconv.ParseFloat(os.Args[3], 64); err != nil {
		log.Fatal(err)
	}
	if exitPercent, err = strconv.ParseFloat(os.Args[4], 64); err != nil {
		log.Fatal(err)
	}
}

// Check for any user input
func checkStdin(inputChan chan<- rune) {
	var ch rune
	fmt.Scanf("%c", &ch)
	inputChan <- ch
}

// Infinite loop
func runMainLoop(inputChan <-chan rune) {
	positionChan := make(chan float64)

	var (
		trades    bitfinex.Trades
		orders    bitfinex.Orders
		start     time.Time
		position  float64
		theo      float64
		stdev     float64
		lastTrade int
	)

	for {
		// Record time for each iteration
		start = time.Now()

		// Cancel orders and exit if anything entered by user
		select {
		case <-inputChan:
			exit()
			return
		default: // Continue if nothing on chan
		}

		trades = getTrades()
		if !apiErrors && trades[0].TID != lastTrade { // If new trades
			go checkPosition(positionChan)
			// Do calcs on trade data while waiting for position data
			theo = calculateTheo(trades)
			stdev = calculateStdev(trades)
			position = <-positionChan
			if (math.Abs(theo-orderTheo) >= MINCHANGE || math.Abs(position-
				orderPos) >= MINO || !liveOrders) && !apiErrors {
				orders = sendOrders(theo, position, stdev)
			}
		}

		if !apiErrors {
			printResults(orders, position, stdev, theo, start)
			// Reset for next iteration
			lastTrade = trades[0].TID
		}

		// Reset for next iteration
		apiErrors = false
	}
}

// Send orders to the exchange
func sendOrders(theo, position, stdev float64) bitfinex.Orders {
	if liveOrders {
		cancelAll()
	}
	liveOrders = true
	orderTheo = theo
	orderPos = position

	// Send new order request to the exchange
	params := calculateOrderParams(position, theo, stdev)
	orders, err := api.MultipleNewOrders(params)
	checkErr(err, "MultipleNewOrders")
	if orders.Message != "" {
		cancelAll()
		log.Printf("Order Message: %s\n", orders.Message)
	}
	return orders
}

func calculateOrderParams(position, theo, stdev float64) []bitfinex.OrderParams {
	var params []bitfinex.OrderParams

	if math.Abs(position) < MINO { // No position
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, maxPos, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	} else if position < (-1*maxPos)+MINO { // Max short postion
		params = []bitfinex.OrderParams{
			{SYMBOL, -1 * position, theo - math.Max(stdev, minEdge)*exitPercent, "bitfinex", "buy", "limit"},
		}
	} else if position > maxPos-MINO { // Max long postion
		params = []bitfinex.OrderParams{
			{SYMBOL, position, theo + math.Max(stdev, minEdge)*exitPercent, "bitfinex", "sell", "limit"},
		}
	} else if (-1*maxPos)+MINO <= position && position <= -1*MINO { // Partial short
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, -1 * position, theo - math.Max(stdev, minEdge)*exitPercent, "bitfinex", "buy", "limit"},
			{SYMBOL, maxPos + position, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	} else if MINO <= position && position <= maxPos-MINO { // Partial long
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos - position, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, position, theo + math.Max(stdev, minEdge)*exitPercent, "bitfinex", "sell", "limit"},
			{SYMBOL, maxPos, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	}

	return params
}

func checkPosition(positionChan chan<- float64) {
	var position float64
	posSlice, err := api.ActivePositions()
	checkErr(err, "ActivePositions")
	for _, pos := range posSlice {
		if pos.Symbol == SYMBOL {
			position = pos.Amount
		}
	}

	positionChan <- position
}

// Get trade data
func getTrades() bitfinex.Trades {
	trades, err := api.Trades(SYMBOL, TRADENUM)
	checkErr(err, "Trades")

	return trades
}

// Calculate a volume and time weighted average of traded prices
func calculateTheo(trades bitfinex.Trades) float64 {
	weightDuration := 60 // number of seconds back for a 50% weight relative to most recent
	mostRecent := trades[0].Timestamp
	var weight, timeDivisor, sum, weightTotal float64

	for _, trade := range trades {
		timeDivisor = float64(mostRecent - trade.Timestamp + weightDuration)
		weight = trade.Amount / timeDivisor
		sum += trade.Price * weight
		weightTotal += weight
	}

	return sum / weightTotal
}

func calculateStdev(trades bitfinex.Trades) float64 {
	x := make(stat.Float64Slice, len(trades)-1)
	for i := 1; i < len(trades); i++ {
		x[i-1] = trades[i-1].Price - trades[i].Price
	}
	return stdMult * stat.Sd(x)
}

// Called on any error
func checkErr(err error, methodName string) {
	if err != nil {
		cancelAll()
		log.Printf("%s Error: %s\n", methodName, err)
		apiErrors = true
	}
}

// Call on exit
func exit() {
	cancelAll()
	fmt.Println("\nCancelled all orders.")
}

// Cancel all orders
func cancelAll() {
	cancelled := false
	for !cancelled {
		cancelled, _ = api.CancelAll()
	}
	liveOrders = false
}

// Print results
func printResults(orders bitfinex.Orders, position, stdev, theo float64, start time.Time) {

	clearScreen()

	fmt.Printf("\nPosition: %.2f\n", position)
	fmt.Printf("Stdev:    %.4f\n", stdev)
	fmt.Printf("Theo:     %.4f\n", theo)

	fmt.Println("\nActive orders:")
	for _, order := range orders.Orders {
		fmt.Printf("%7.2f %s @ %6.4f\n", order.Amount, SYMBOL, order.Price)
	}

	fmt.Printf("\n%v processing time...", time.Since(start))
}

// Clear the terminal between prints
func clearScreen() {
	c := exec.Command("clear")
	c.Stdout = os.Stdout
	c.Run()
}
<commit_msg>change instrument<commit_after>package main

import (
	"bitmm/bitfinex"
	"fmt"
	"github.com/grd/stat"
	"log"
	"math"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"time"
)

// Trade inputs
const (
	SYMBOL    = "ltcusd" // Instrument to trade
	MINCHANGE = 0.0005   // Minumum change required to update prices
	TRADENUM  = 40       // Number of trades to use in calculations
	MINO      = 0.25     // Min order size
)

var (
	api        = bitfinex.New(os.Getenv("BITFINEX_KEY"), os.Getenv("BITFINEX_SECRET"))
	apiErrors  = false // Set to true on any error
	liveOrders = false // Set to true on any order
	orderTheo  = 0.0   // Theo value on which the live orders are based
	orderPos   = 0.0   // Position on which the live orders are based
	// Fed in as OS args:
	maxPos      float64 // Maximum Position size
	minEdge     float64 // Minimum edge for position entry
	stdMult     float64 // Multiplier for standard deviation
	exitPercent float64 // Percent of edge for position exit
)

func main() {
	if len(os.Args) < 5 {
		fmt.Printf("usage: %s <size> <minimum edge> <stdev multiplier> <exit percent edge>\n",
			filepath.Base(os.Args[0]))
		os.Exit(1)
	}

	fmt.Println("\nInitializing...")

	// Set file for logging
	logFile, err := os.OpenFile("bitmm_log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatal(err)
	}
	defer logFile.Close()
	log.SetOutput(logFile)

	// Get maxPos, minEdge, exitPercent from user input
	getArgs()

	// Check for input to break loop
	inputChan := make(chan rune)
	go checkStdin(inputChan)

	// Run loop until user input is received
	runMainLoop(inputChan)
}

func getArgs() {
	var err error
	if maxPos, err = strconv.ParseFloat(os.Args[1], 64); err != nil {
		log.Fatal(err)
	}
	if minEdge, err = strconv.ParseFloat(os.Args[2], 64); err != nil {
		log.Fatal(err)
	}
	if stdMult, err = strconv.ParseFloat(os.Args[3], 64); err != nil {
		log.Fatal(err)
	}
	if exitPercent, err = strconv.ParseFloat(os.Args[4], 64); err != nil {
		log.Fatal(err)
	}
}

// Check for any user input
func checkStdin(inputChan chan<- rune) {
	var ch rune
	fmt.Scanf("%c", &ch)
	inputChan <- ch
}

// Infinite loop
func runMainLoop(inputChan <-chan rune) {
	positionChan := make(chan float64)

	var (
		trades    bitfinex.Trades
		orders    bitfinex.Orders
		start     time.Time
		position  float64
		theo      float64
		stdev     float64
		lastTrade int
	)

	for {
		// Record time for each iteration
		start = time.Now()

		// Cancel orders and exit if anything entered by user
		select {
		case <-inputChan:
			exit()
			return
		default: // Continue if nothing on chan
		}

		trades = getTrades()
		if !apiErrors && trades[0].TID != lastTrade { // If new trades
			go checkPosition(positionChan)
			// Do calcs on trade data while waiting for position data
			theo = calculateTheo(trades)
			stdev = calculateStdev(trades)
			position = <-positionChan
			if (math.Abs(theo-orderTheo) >= MINCHANGE || math.Abs(position-
				orderPos) >= MINO || !liveOrders) && !apiErrors {
				orders = sendOrders(theo, position, stdev)
			}
		}

		if !apiErrors {
			printResults(orders, position, stdev, theo, start)
			// Reset for next iteration
			lastTrade = trades[0].TID
		}

		// Reset for next iteration
		apiErrors = false
	}
}

// Send orders to the exchange
func sendOrders(theo, position, stdev float64) bitfinex.Orders {
	if liveOrders {
		cancelAll()
	}
	liveOrders = true
	orderTheo = theo
	orderPos = position

	// Send new order request to the exchange
	params := calculateOrderParams(position, theo, stdev)
	orders, err := api.MultipleNewOrders(params)
	checkErr(err, "MultipleNewOrders")

	if orders.Message != "" {
		cancelAll()
		log.Printf("Order Message: %s\n", orders.Message)
	}

	return orders
}

func calculateOrderParams(position, theo, stdev float64) []bitfinex.OrderParams {
	var params []bitfinex.OrderParams

	if math.Abs(position) < MINO { // No position
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, maxPos, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	} else if position < (-1*maxPos)+MINO { // Max short postion
		params = []bitfinex.OrderParams{
			{SYMBOL, -1 * position, theo - math.Max(stdev, minEdge)*exitPercent, "bitfinex", "buy", "limit"},
		}
	} else if position > maxPos-MINO { // Max long postion
		params = []bitfinex.OrderParams{
			{SYMBOL, position, theo + math.Max(stdev, minEdge)*exitPercent, "bitfinex", "sell", "limit"},
		}
	} else if (-1*maxPos)+MINO <= position && position <= -1*MINO { // Partial short
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, -1 * position, theo - math.Max(stdev, minEdge)*exitPercent, "bitfinex", "buy", "limit"},
			{SYMBOL, maxPos + position, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	} else if MINO <= position && position <= maxPos-MINO { // Partial long
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos - position, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, position, theo + math.Max(stdev, minEdge)*exitPercent, "bitfinex", "sell", "limit"},
			{SYMBOL, maxPos, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	}

	return params
}

func checkPosition(positionChan chan<- float64) {
	var position float64
	posSlice, err := api.ActivePositions()
	checkErr(err, "ActivePositions")
	for _, pos := range posSlice {
		if pos.Symbol == SYMBOL {
			position = pos.Amount
		}
	}

	positionChan <- position
}

// Get trade data
func getTrades() bitfinex.Trades {
	trades, err := api.Trades(SYMBOL, TRADENUM)
	checkErr(err, "Trades")

	return trades
}

// Calculate a volume and time weighted average of traded prices
func calculateTheo(trades bitfinex.Trades) float64 {
	weightDuration := 60 // number of seconds back for a 50% weight relative to most recent
	mostRecent := trades[0].Timestamp
	var weight, timeDivisor, sum, weightTotal float64

	for _, trade := range trades {
		timeDivisor = float64(mostRecent - trade.Timestamp + weightDuration)
		weight = trade.Amount / timeDivisor
		sum += trade.Price * weight
		weightTotal += weight
	}

	return sum / weightTotal
}

func calculateStdev(trades bitfinex.Trades) float64 {
	x := make(stat.Float64Slice, len(trades)-1)
	for i := 1; i < len(trades); i++ {
		x[i-1] = trades[i-1].Price - trades[i].Price
	}
	return stdMult * stat.Sd(x)
}

// Called on any error
func checkErr(err error, methodName string) {
	if err != nil {
		cancelAll()
		log.Printf("%s Error: %s\n", methodName, err)
		apiErrors = true
	}
}

// Call on exit
func exit() {
	cancelAll()
	fmt.Println("\nCancelled all orders.")
}

// Cancel all orders
func cancelAll() {
	cancelled := false
	for !cancelled {
		cancelled, _ = api.CancelAll()
	}
	liveOrders = false
}

// Print results
func printResults(orders bitfinex.Orders, position, stdev, theo float64, start time.Time) {

	clearScreen()

	fmt.Printf("\nPosition: %.2f\n", position)
	fmt.Printf("Stdev:    %.4f\n", stdev)
	fmt.Printf("Theo:     %.4f\n", theo)

	fmt.Println("\nActive orders:")
	for _, order := range orders.Orders {
		fmt.Printf("%7.2f %s @ %6.4f\n", order.Amount, SYMBOL, order.Price)
	}

	fmt.Printf("\n%v processing time...", time.Since(start))
}

// Clear the terminal between prints
func clearScreen() {
	c := exec.Command("clear")
	c.Stdout = os.Stdout
	c.Run()
}
<|endoftext|>


<commit_before>package main

import (
	"bitmm/bitfinex"
	"fmt"
	"github.com/grd/stat"
	"log"
	"math"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"time"
)

// Trade inputs
const (
	SYMBOL    = "ltcusd" // Instrument to trade
	MINCHANGE = 0.0025   // Minumum change required to update prices
	TRADENUM  = 25       // Number of trades to use in calculations
	MINO      = 0.5      // Min order size
)

var (
	api        = bitfinex.New(os.Getenv("BITFINEX_KEY"), os.Getenv("BITFINEX_SECRET"))
	apiErrors  = false // Set to true on any error
	liveOrders = false // Set to true on any order
	orderTheo  = 0.0   // Theo value on which the live orders are based
	orderPos   = 0.0   // Position on which the live orders are based
	// Fed in as OS args:
	maxPos      float64 // Maximum Position size
	minEdge     float64 // Minimum edge for position entry
	stdMult     float64 // Multiplier for standard deviation
	exitPercent float64 // Percent of edge for position exit
)

func main() {
	if len(os.Args) < 5 {
		fmt.Printf("usage: %s <size> <minimum edge> <stdev multiplier> <exit percent edge>\n",
			filepath.Base(os.Args[0]))
		os.Exit(1)
	}

	fmt.Println("\nInitializing...")

	// Get maxPos, minEdge, exitPercent from user input
	getArgs()

	// Check for input to break loop
	inputChan := make(chan rune)
	go checkStdin(inputChan)

	// Run loop until user input is received
	runMainLoop(inputChan)
}

func getArgs() {
	var err error
	if maxPos, err = strconv.ParseFloat(os.Args[1], 64); err != nil {
		log.Fatal(err)
	}
	if minEdge, err = strconv.ParseFloat(os.Args[2], 64); err != nil {
		log.Fatal(err)
	}
	if stdMult, err = strconv.ParseFloat(os.Args[3], 64); err != nil {
		log.Fatal(err)
	}
	if exitPercent, err = strconv.ParseFloat(os.Args[4], 64); err != nil {
		log.Fatal(err)
	}
}

// Check for any user input
func checkStdin(inputChan chan<- rune) {
	var ch rune
	fmt.Scanf("%c", &ch)
	inputChan <- ch
}

// Infinite loop
func runMainLoop(inputChan <-chan rune) {
	positionChan := make(chan float64)

	var (
		trades    bitfinex.Trades
		orders    bitfinex.Orders
		start     time.Time
		position  float64
		theo      float64
		stdev     float64
		lastTrade int
	)

	for {
		// Record time for each iteration
		start = time.Now()

		// Cancel orders and exit if anything entered by user
		select {
		case <-inputChan:
			exit()
			return
		default: // Continue if nothing on chan
		}

		trades = getTrades()
		if !apiErrors && trades[0].TID != lastTrade { // If new trades
			go checkPosition(positionChan)
			// Do calcs on trade data while waiting for position data
			theo = calculateTheo(trades)
			stdev = calculateStdev(trades)
			position = <-positionChan
			if (math.Abs(theo-orderTheo) >= MINCHANGE || math.Abs(position-
				orderPos) >= MINO || !liveOrders) && !apiErrors {
				orders = sendOrders(theo, position, stdev)
			}
		}

		if !apiErrors {
			printResults(orders, position, stdev, theo, start)
			// Reset for next iteration
			lastTrade = trades[0].TID
		}

		// Reset for next iteration
		apiErrors = false
	}
}

// Send orders to the exchange
func sendOrders(theo, position, stdev float64) bitfinex.Orders {
	if liveOrders {
		cancelAll()
	}

	// Send new order request to the exchange
	params := calculateOrderParams(position, theo, stdev)
	orders, err := api.MultipleNewOrders(params)
	checkErr(err)
	if err == nil {
		liveOrders = true
		orderTheo = theo
		orderPos = position
	}
	return orders
}

func calculateOrderParams(position, theo, stdev float64) []bitfinex.OrderParams {
	var params []bitfinex.OrderParams

	if math.Abs(position) < MINO { // No position
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, maxPos, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	} else if position < (-1*maxPos)+MINO { // Max short postion
		params = []bitfinex.OrderParams{
			{SYMBOL, -1 * position, theo - math.Max(stdev, minEdge)*exitPercent, "bitfinex", "buy", "limit"},
		}
	} else if position > maxPos-MINO { // Max long postion
		params = []bitfinex.OrderParams{
			{SYMBOL, position, theo + math.Max(stdev, minEdge)*exitPercent, "bitfinex", "sell", "limit"},
		}
	} else if (-1*maxPos)+MINO <= position && position <= -1*MINO { // Partial short
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, -1 * position, theo - math.Max(stdev, minEdge)*exitPercent, "bitfinex", "buy", "limit"},
			{SYMBOL, maxPos + position, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	} else if MINO <= position && position <= maxPos-MINO { // Partial long
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos - position, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, position, theo + math.Max(stdev, minEdge)*exitPercent, "bitfinex", "sell", "limit"},
			{SYMBOL, maxPos, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	}

	return params
}

func checkPosition(positionChan chan<- float64) {
	var position float64
	posSlice, err := api.ActivePositions()
	checkErr(err)
	for _, pos := range posSlice {
		if pos.Symbol == SYMBOL {
			position = pos.Amount
		}
	}

	positionChan <- position
}

// Get trade data
func getTrades() bitfinex.Trades {
	trades, err := api.Trades(SYMBOL, TRADENUM)
	checkErr(err)

	return trades
}

// Calculate a volume and time weighted average of traded prices
func calculateTheo(trades bitfinex.Trades) float64 {
	weightDuration := 60 // number of seconds back for a 50% weight relative to most recent
	mostRecent := trades[0].Timestamp
	var weight, timeDivisor, sum, weightTotal float64

	for _, trade := range trades {
		timeDivisor = float64(mostRecent - trade.Timestamp + weightDuration)
		weight = trade.Amount / timeDivisor
		sum += trade.Price * weight
		weightTotal += weight
	}

	return sum / weightTotal
}

func calculateStdev(trades bitfinex.Trades) float64 {
	x := make(stat.Float64Slice, len(trades)-1)
	for i := 1; i < len(trades); i++ {
		x[i-1] = trades[i-1].Price - trades[i].Price
	}
	return stdMult * stat.Sd(x)
}

// Called on any error
func checkErr(err error) {
	if err != nil {
		cancelAll()
		log.Println(err)
		apiErrors = true
	}
}

// Call on exit
func exit() {
	cancelAll()
	fmt.Println("\nCancelled all orders.")
}

// Cancel all orders
func cancelAll() {
	cancelled := false
	for !cancelled {
		cancelled, _ = api.CancelAll()
	}
	liveOrders = false
}

// Print results
func printResults(orders bitfinex.Orders, position, stdev, theo float64, start time.Time) {

	clearScreen()

	fmt.Printf("\nPosition: %.2f\n", position)
	fmt.Printf("Stdev:    %.4f\n", stdev)
	fmt.Printf("Theo:     %.4f\n", theo)

	fmt.Println("\nActive orders:")
	for _, order := range orders.Orders {
		fmt.Printf("%7.2f %s @ %6.4f\n", order.Amount, SYMBOL, order.Price)
	}

	fmt.Printf("\n%v processing time...", time.Since(start))
}

// Clear the terminal between prints
func clearScreen() {
	c := exec.Command("clear")
	c.Stdout = os.Stdout
	c.Run()
}
<commit_msg>change to 50 trades and no min for exit<commit_after>package main

import (
	"bitmm/bitfinex"
	"fmt"
	"github.com/grd/stat"
	"log"
	"math"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"time"
)

// Trade inputs
const (
	SYMBOL    = "ltcusd" // Instrument to trade
	MINCHANGE = 0.0025   // Minumum change required to update prices
	TRADENUM  = 50       // Number of trades to use in calculations
	MINO      = 0.5      // Min order size
)

var (
	api        = bitfinex.New(os.Getenv("BITFINEX_KEY"), os.Getenv("BITFINEX_SECRET"))
	apiErrors  = false // Set to true on any error
	liveOrders = false // Set to true on any order
	orderTheo  = 0.0   // Theo value on which the live orders are based
	orderPos   = 0.0   // Position on which the live orders are based
	// Fed in as OS args:
	maxPos      float64 // Maximum Position size
	minEdge     float64 // Minimum edge for position entry
	stdMult     float64 // Multiplier for standard deviation
	exitPercent float64 // Percent of edge for position exit
)

func main() {
	if len(os.Args) < 5 {
		fmt.Printf("usage: %s <size> <minimum edge> <stdev multiplier> <exit percent edge>\n",
			filepath.Base(os.Args[0]))
		os.Exit(1)
	}

	fmt.Println("\nInitializing...")

	// Get maxPos, minEdge, exitPercent from user input
	getArgs()

	// Check for input to break loop
	inputChan := make(chan rune)
	go checkStdin(inputChan)

	// Run loop until user input is received
	runMainLoop(inputChan)
}

func getArgs() {
	var err error
	if maxPos, err = strconv.ParseFloat(os.Args[1], 64); err != nil {
		log.Fatal(err)
	}
	if minEdge, err = strconv.ParseFloat(os.Args[2], 64); err != nil {
		log.Fatal(err)
	}
	if stdMult, err = strconv.ParseFloat(os.Args[3], 64); err != nil {
		log.Fatal(err)
	}
	if exitPercent, err = strconv.ParseFloat(os.Args[4], 64); err != nil {
		log.Fatal(err)
	}
}

// Check for any user input
func checkStdin(inputChan chan<- rune) {
	var ch rune
	fmt.Scanf("%c", &ch)
	inputChan <- ch
}

// Infinite loop
func runMainLoop(inputChan <-chan rune) {
	positionChan := make(chan float64)

	var (
		trades    bitfinex.Trades
		orders    bitfinex.Orders
		start     time.Time
		position  float64
		theo      float64
		stdev     float64
		lastTrade int
	)

	for {
		// Record time for each iteration
		start = time.Now()

		// Cancel orders and exit if anything entered by user
		select {
		case <-inputChan:
			exit()
			return
		default: // Continue if nothing on chan
		}

		trades = getTrades()
		if !apiErrors && trades[0].TID != lastTrade { // If new trades
			go checkPosition(positionChan)
			// Do calcs on trade data while waiting for position data
			theo = calculateTheo(trades)
			stdev = calculateStdev(trades)
			position = <-positionChan
			if (math.Abs(theo-orderTheo) >= MINCHANGE || math.Abs(position-
				orderPos) >= MINO || !liveOrders) && !apiErrors {
				orders = sendOrders(theo, position, stdev)
			}
		}

		if !apiErrors {
			printResults(orders, position, stdev, theo, start)
			// Reset for next iteration
			lastTrade = trades[0].TID
		}

		// Reset for next iteration
		apiErrors = false
	}
}

// Send orders to the exchange
func sendOrders(theo, position, stdev float64) bitfinex.Orders {
	if liveOrders {
		cancelAll()
	}

	// Send new order request to the exchange
	params := calculateOrderParams(position, theo, stdev)
	orders, err := api.MultipleNewOrders(params)
	checkErr(err)
	if err == nil {
		liveOrders = true
		orderTheo = theo
		orderPos = position
	}
	return orders
}

func calculateOrderParams(position, theo, stdev float64) []bitfinex.OrderParams {
	var params []bitfinex.OrderParams

	if math.Abs(position) < MINO { // No position
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, maxPos, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	} else if position < (-1*maxPos)+MINO { // Max short postion
		params = []bitfinex.OrderParams{
			{SYMBOL, -1 * position, theo - stdev*exitPercent, "bitfinex", "buy", "limit"},
		}
	} else if position > maxPos-MINO { // Max long postion
		params = []bitfinex.OrderParams{
			{SYMBOL, position, theo + stdev*exitPercent, "bitfinex", "sell", "limit"},
		}
	} else if (-1*maxPos)+MINO <= position && position <= -1*MINO { // Partial short
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, -1 * position, theo - stdev*exitPercent, "bitfinex", "buy", "limit"},
			{SYMBOL, maxPos + position, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	} else if MINO <= position && position <= maxPos-MINO { // Partial long
		params = []bitfinex.OrderParams{
			{SYMBOL, maxPos - position, theo - math.Max(stdev, minEdge), "bitfinex", "buy", "limit"},
			{SYMBOL, position, theo + stdev*exitPercent, "bitfinex", "sell", "limit"},
			{SYMBOL, maxPos, theo + math.Max(stdev, minEdge), "bitfinex", "sell", "limit"},
		}
	}

	return params
}

func checkPosition(positionChan chan<- float64) {
	var position float64
	posSlice, err := api.ActivePositions()
	checkErr(err)
	for _, pos := range posSlice {
		if pos.Symbol == SYMBOL {
			position = pos.Amount
		}
	}

	positionChan <- position
}

// Get trade data
func getTrades() bitfinex.Trades {
	trades, err := api.Trades(SYMBOL, TRADENUM)
	checkErr(err)

	return trades
}

// Calculate a volume and time weighted average of traded prices
func calculateTheo(trades bitfinex.Trades) float64 {
	weightDuration := 60 // number of seconds back for a 50% weight relative to most recent
	mostRecent := trades[0].Timestamp
	var weight, timeDivisor, sum, weightTotal float64

	for _, trade := range trades {
		timeDivisor = float64(mostRecent - trade.Timestamp + weightDuration)
		weight = trade.Amount / timeDivisor
		sum += trade.Price * weight
		weightTotal += weight
	}

	return sum / weightTotal
}

func calculateStdev(trades bitfinex.Trades) float64 {
	x := make(stat.Float64Slice, len(trades)-1)
	for i := 1; i < len(trades); i++ {
		x[i-1] = trades[i-1].Price - trades[i].Price
	}
	return stdMult * stat.Sd(x)
}

// Called on any error
func checkErr(err error) {
	if err != nil {
		cancelAll()
		log.Println(err)
		apiErrors = true
	}
}

// Call on exit
func exit() {
	cancelAll()
	fmt.Println("\nCancelled all orders.")
}

// Cancel all orders
func cancelAll() {
	cancelled := false
	for !cancelled {
		cancelled, _ = api.CancelAll()
	}
	liveOrders = false
}

// Print results
func printResults(orders bitfinex.Orders, position, stdev, theo float64, start time.Time) {

	clearScreen()

	fmt.Printf("\nPosition: %.2f\n", position)
	fmt.Printf("Stdev:    %.4f\n", stdev)
	fmt.Printf("Theo:     %.4f\n", theo)

	fmt.Println("\nActive orders:")
	for _, order := range orders.Orders {
		fmt.Printf("%7.2f %s @ %6.4f\n", order.Amount, SYMBOL, order.Price)
	}

	fmt.Printf("\n%v processing time...", time.Since(start))
}

// Clear the terminal between prints
func clearScreen() {
	c := exec.Command("clear")
	c.Stdout = os.Stdout
	c.Run()
}
<|endoftext|>


<commit_before>package assert

import (
	"bytes"
	"fmt"
	"reflect"
)

type T interface {
	Fail()
}

type logFacade struct {
	t      T
	logger logger
}

type assertion struct {
	logFacade *logFacade
}

func GetAssertion(t T) *assertion {
	return &assertion{&logFacade{t, theLogger}}
}

func fail(log *logFacade, message string) bool {
	log.logger.Log(assertLocation(2), message)
	log.t.Fail()
	return false
}

func objectEqual(expected, actual interface{}) bool {
	if expected == nil || actual == nil {
		return expected == actual
	}
	if exp, ok := expected.([]byte); ok {
		if act, ok := actual.([]byte); ok {
			return bytes.Equal(exp, act)
		}
	}
	return reflect.DeepEqual(expected, actual)
}

func (a *assertion) Equal(expected, actual interface{}) bool {
	if !objectEqual(expected, actual) {
		return fail(a.logFacade, fmt.Sprintf("Expected %v but found %v.", expected, actual))
	}
	return true
}
<commit_msg>change mutable assertion to immutable<commit_after>package assert

import (
	"bytes"
	"fmt"
	"reflect"
)

type T interface {
	Fail()
}

type logFacade struct {
	t      T
	logger logger
}

type assertion struct {
	logFacade logFacade
}

func GetAssertion(t T) assertion {
	return assertion{logFacade{t, theLogger}}
}

func fail(log logFacade, message string) bool {
	log.logger.Log(assertLocation(2), message)
	log.t.Fail()
	return false
}

func objectEqual(expected, actual interface{}) bool {
	if expected == nil || actual == nil {
		return expected == actual
	}
	if exp, ok := expected.([]byte); ok {
		if act, ok := actual.([]byte); ok {
			return bytes.Equal(exp, act)
		}
	}
	return reflect.DeepEqual(expected, actual)
}

func (a assertion) Equal(expected, actual interface{}) bool {
	if !objectEqual(expected, actual) {
		return fail(a.logFacade, fmt.Sprintf("Expected %v but found %v.", expected, actual))
	}
	return true
}
<|endoftext|>


<commit_before>package auth

import (
	"encoding/base64"
	"net/http"
	"strings"
)

// Basic returns a Handler that authenticates via Basic Auth. Writes a http.StatusUnauthorized
// if authentication fails.
func Basic(username string, password string) http.HandlerFunc {
	var siteAuth = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
	return func(res http.ResponseWriter, req *http.Request) {
		auth := req.Header.Get("Authorization")
		if !SecureCompare(auth, "Basic "+siteAuth) {
			unauthorized(res, "Authorization Required")
		}
	}
}

// BasicFunc returns a Handler that authenticates via Basic Auth using the provided function.
// The function should return true for a valid username/password combination.
func BasicFunc(authfn func(string, string) bool) http.HandlerFunc {
	return func(res http.ResponseWriter, req *http.Request) {
		auth := req.Header.Get("Authorization")
		if len(auth) < 6 || auth[:6] != "Basic " {
			unauthorized(res, "Authorization Required")
			return
		}
		b, err := base64.StdEncoding.DecodeString(auth[6:])
		if err != nil {
			unauthorized(res, "Authorization Required")
			return
		}
		tokens := strings.SplitN(string(b), ":", 2)
		if len(tokens) != 2 || !authfn(tokens[0], tokens[1]) {
			unauthorized(res, "Authorization Required")
		}
	}
}

func unauthorized(res http.ResponseWriter, realm string) {
	res.Header().Set("WWW-Authenticate", "Basic realm=\"" + realm + "\"")
	http.Error(res, "Not Authorized", http.StatusUnauthorized)
}
<commit_msg>move realm to a variable (see #6)<commit_after>package auth

import (
	"encoding/base64"
	"net/http"
	"strings"
)

// Realm is used when setting the WWW-Authenticate response header.
var Realm = "Authorization Required"

// Basic returns a Handler that authenticates via Basic Auth. Writes a http.StatusUnauthorized
// if authentication fails.
func Basic(username string, password string) http.HandlerFunc {
	var siteAuth = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
	return func(res http.ResponseWriter, req *http.Request) {
		auth := req.Header.Get("Authorization")
		if !SecureCompare(auth, "Basic "+siteAuth) {
			unauthorized(res)
		}
	}
}

// BasicFunc returns a Handler that authenticates via Basic Auth using the provided function.
// The function should return true for a valid username/password combination.
func BasicFunc(authfn func(string, string) bool) http.HandlerFunc {
	return func(res http.ResponseWriter, req *http.Request) {
		auth := req.Header.Get("Authorization")
		if len(auth) < 6 || auth[:6] != "Basic " {
			unauthorized(res)
			return
		}
		b, err := base64.StdEncoding.DecodeString(auth[6:])
		if err != nil {
			unauthorized(res)
			return
		}
		tokens := strings.SplitN(string(b), ":", 2)
		if len(tokens) != 2 || !authfn(tokens[0], tokens[1]) {
			unauthorized(res)
		}
	}
}

func unauthorized(res http.ResponseWriter) {
	res.Header().Set("WWW-Authenticate", "Basic realm=\"" + Realm + "\"")
	http.Error(res, "Not Authorized", http.StatusUnauthorized)
}
<|endoftext|>


<commit_before>// Copyright 2013 Dmitry Chestnykh. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package assets implements loading, concatenating, and filtering of assets.
package assets

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"

	"github.com/dchest/kkr/filters"
	"github.com/dchest/kkr/utils"
)

const bufSigil = '$'

type Asset struct {
	Name      string      `yaml:"name"`
	Filter    interface{} `yaml:"filter,omitempty"`
	Files     []string    `yaml:"files"`
	Separator string      `yaml:"separator,omitempty"`
	OutName   string      `yaml:"outname"`

	// Result is output filename, if OutName is "$", the content of output.
	Result string

	processed bool
}

type Collection struct {
	assets  map[string]*Asset
	filters *filters.Collection
}

// Load loads an asset collection from the given assets config file and returns it.
func Load(filename string) (c *Collection, err error) {
	// Load assets description from file (or create a new).
	var assets []*Asset
	err = utils.UnmarshallYAMLFile(filename, &assets)
	if err != nil {
		if os.IsNotExist(err) {
			// No assets file is not an error,
			// create an empty collection.
			assets = make([]*Asset, 0)
			err = nil
		} else {
			return
		}
	}

	// Put assets into a map addressed by name and load filters.
	c = &Collection{
		assets:  make(map[string]*Asset),
		filters: filters.NewCollection(),
	}
	for _, v := range assets {
		if _, exists := c.assets[v.Name]; exists {
			return nil, fmt.Errorf("duplicate asset name %q", v.Name)
		}
		c.assets[v.Name] = v
		if v.Filter != nil {
			c.filters.AddFromYAML(v.Name, v.Filter)
		}
	}
	return c, nil
}

// Process processes all assets in the collection.
func (c *Collection) Process(outdir string) error {
	for _, a := range c.assets {
		if err := c.ProcessAsset(a, c.filters, outdir); err != nil {
			return err
		}
	}
	return nil
}

func (c *Collection) SetStringAsset(name, data string) {
	c.assets[name] = &Asset{
		Name:      name,
		OutName:   "$",
		Result:    data,
		processed: true,
	}
}

// Get returns an asset by name or nil if there's no such asset.
func (c *Collection) Get(name string) *Asset {
	return c.assets[name]
}

func concatFiles(filenames []string, separator []byte) (out []byte, err error) {
	for i, f := range filenames {
		if len(f) > 0 && f[0] == bufSigil {
			// Not a file, skip for now.
			continue
		}
		b, err := ioutil.ReadFile(f)
		if err != nil {
			return nil, err
		}
		out = append(out, b...)
		if i != len(filenames)-1 {
			out = append(out, separator...)
		}
	}
	return out, nil
}

func (c *Collection) ProcessAsset(a *Asset, filters *filters.Collection, outdir string) error {
	separator := a.Separator
	// Concatenate files.
	b, err := concatFiles(a.Files, []byte(separator))
	if err != nil {
		return err
	}
	// Append buffers if any.
	for i, f := range a.Files {
		if len(f) > 0 && f[0] == bufSigil {
			refAsset := c.Get(f[1:]) // e.g. $global-style -> global-style
			if refAsset == nil {
				return fmt.Errorf("asset %q not found", f[1:])
			}
			if !refAsset.processed {
				// Process it.
				// BUG Here hang if we can have a circular reference.
				if err := c.ProcessAsset(refAsset, filters, outdir); err != nil {
					return err
				}
			}
			b = append(b, []byte(refAsset.Result)...)
			if i != len(a.Files)-1 {
				b = append(b, separator...)
			}
		}
	}
	// Filter result.
	s, err := filters.ApplyFilter(a.Name, string(b))
	if err != nil {
		return err
	}
	if a.OutName == string(bufSigil) {
		// Result is output.
		// Don't write to file, just remember result.
		a.Result = s
		a.processed = true
		log.Printf("A %c%s", bufSigil, a.Name)
		return nil
	}
	// Result is filename.
	// Make file name from hash.
	a.Result = utils.TemplatedHash(a.OutName, s)
	// Check that the result is not empty.
	if a.Result == "" {
		// Use hash for name.
		a.Result = string(utils.Hash(s))
	}
	log.Printf("A %s", a.Result)
	// Write to file.
	outfile := filepath.Join(outdir, filepath.FromSlash(a.Result))
	if err := utils.WriteStringToFile(outfile, s); err != nil {
		return err
	}
	a.processed = true
	return nil
}
<commit_msg>Ignore processed assets<commit_after>// Copyright 2013 Dmitry Chestnykh. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package assets implements loading, concatenating, and filtering of assets.
package assets

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"

	"github.com/dchest/kkr/filters"
	"github.com/dchest/kkr/utils"
)

const bufSigil = '$'

type Asset struct {
	Name      string      `yaml:"name"`
	Filter    interface{} `yaml:"filter,omitempty"`
	Files     []string    `yaml:"files"`
	Separator string      `yaml:"separator,omitempty"`
	OutName   string      `yaml:"outname"`

	// Result is output filename, if OutName is "$", the content of output.
	Result string

	processed bool
}

type Collection struct {
	assets  map[string]*Asset
	filters *filters.Collection
}

// Load loads an asset collection from the given assets config file and returns it.
func Load(filename string) (c *Collection, err error) {
	// Load assets description from file (or create a new).
	var assets []*Asset
	err = utils.UnmarshallYAMLFile(filename, &assets)
	if err != nil {
		if os.IsNotExist(err) {
			// No assets file is not an error,
			// create an empty collection.
			assets = make([]*Asset, 0)
			err = nil
		} else {
			return
		}
	}

	// Put assets into a map addressed by name and load filters.
	c = &Collection{
		assets:  make(map[string]*Asset),
		filters: filters.NewCollection(),
	}
	for _, v := range assets {
		if _, exists := c.assets[v.Name]; exists {
			return nil, fmt.Errorf("duplicate asset name %q", v.Name)
		}
		c.assets[v.Name] = v
		if v.Filter != nil {
			c.filters.AddFromYAML(v.Name, v.Filter)
		}
	}
	return c, nil
}

// Process processes all assets in the collection.
func (c *Collection) Process(outdir string) error {
	for _, a := range c.assets {
		if err := c.ProcessAsset(a, c.filters, outdir); err != nil {
			return err
		}
	}
	return nil
}

func (c *Collection) SetStringAsset(name, data string) {
	c.assets[name] = &Asset{
		Name:      name,
		OutName:   "$",
		Result:    data,
		processed: true,
	}
}

// Get returns an asset by name or nil if there's no such asset.
func (c *Collection) Get(name string) *Asset {
	return c.assets[name]
}

func concatFiles(filenames []string, separator []byte) (out []byte, err error) {
	for i, f := range filenames {
		if len(f) > 0 && f[0] == bufSigil {
			// Not a file, skip for now.
			continue
		}
		b, err := ioutil.ReadFile(f)
		if err != nil {
			return nil, err
		}
		out = append(out, b...)
		if i != len(filenames)-1 {
			out = append(out, separator...)
		}
	}
	return out, nil
}

func (c *Collection) ProcessAsset(a *Asset, filters *filters.Collection, outdir string) error {
	if a.processed {
		return nil
	}
	separator := a.Separator
	// Concatenate files.
	b, err := concatFiles(a.Files, []byte(separator))
	if err != nil {
		return err
	}
	// Append buffers if any.
	for i, f := range a.Files {
		if len(f) > 0 && f[0] == bufSigil {
			refAsset := c.Get(f[1:]) // e.g. $global-style -> global-style
			if refAsset == nil {
				return fmt.Errorf("asset %q not found", f[1:])
			}
			if !refAsset.processed {
				// Process it.
				// BUG Here hang if we can have a circular reference.
				if err := c.ProcessAsset(refAsset, filters, outdir); err != nil {
					return err
				}
			}
			b = append(b, []byte(refAsset.Result)...)
			if i != len(a.Files)-1 {
				b = append(b, separator...)
			}
		}
	}
	// Filter result.
	s, err := filters.ApplyFilter(a.Name, string(b))
	if err != nil {
		return err
	}
	if a.OutName == string(bufSigil) {
		// Result is output.
		// Don't write to file, just remember result.
		a.Result = s
		a.processed = true
		log.Printf("A %c%s", bufSigil, a.Name)
		return nil
	}
	// Result is filename.
	// Make file name from hash.
	a.Result = utils.TemplatedHash(a.OutName, s)
	// Check that the result is not empty.
	if a.Result == "" {
		// Use hash for name.
		a.Result = string(utils.Hash(s))
	}
	log.Printf("A %s", a.Result)
	// Write to file.
	outfile := filepath.Join(outdir, filepath.FromSlash(a.Result))
	if err := utils.WriteStringToFile(outfile, s); err != nil {
		return err
	}
	a.processed = true
	return nil
}
<|endoftext|>