顯示具有 python 標籤的文章。 顯示所有文章
顯示具有 python 標籤的文章。 顯示所有文章

2018年2月9日 星期五

比特幣無風險套利初探

由於比特幣流動性尚未健全的關係,不同地方的交易所存在報價的差異,所以導致了套利的空間,也就是俗稱的 BTC 搬磚。

類似的套利在銀行的外匯交易很常見,通常就是在客戶買進外匯時,做一個反向部位來套利。

國外網友已經開發了一個類似的 Python 程式來執行跨交易所套利,前提是你必須在這些交易所都有帳戶,並且能瞬間即時執行交易,因為套利機會通常是稍縱即逝。

程式目前自動套利交易只支援兩家交易所

  • Bitstamp (USD)
  • Paymium (EUR)

如果我們將設定檔案 config.py 設定為:

  • 鎖定 6% 獲利以上的交易
  • 執行部位小於 2 BTC 大於 0.01 BTC

執行之後就會顯示當時可以套利的機會點:

2018-02-09 18:03:34,738 [INFO] profit: 1051.17 USD with volume: 2.00 BTC - buy at 8490.0000 (KrakenUSD) sell at 8765.1039 (GDAXEUR) ~6.19%

2 BTC 用美元買進 $8490 用歐元賣出 $8765.1039 --> 套利美元 1051.17 USD 獲利率約 6.19%

https://github.com/jdlin/bitcoin-arbitrage

2017年9月17日 星期日

Pyminer -- Python Bitcoin Miner

#!/usr/bin/python
#
# Copyright 2011 Jeff Garzik
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#

2015年5月22日 星期五

TA-Lib Usage (STOCH)


TA-Lib Usage (RSI)


TA-Lib Usage (MACD)




TA-Lib Usage (Bollinger Bands)




TA-Lib Usage (ATR)




Batch Transform

# This is the standard Quantopian function that initializes your data and 
# variables. In it, we define how large of a 'bet' we're making (in dollars) and what 
# stock we're working with.
def initialize(context):
    # we will be trading in AMZN and WMT shares
    context.stocks = symbols('AMZN', 'WMT')
    context.bet_amount = 100000
    context.long = 0

# This is the standard Quantopian event handling function. This function is 
# run once for each bar of data.  In this example, it the min and max 
# prices for the trailing window.  If the price exceeds the recent high, it 
# goes short; if the price dips below the recent low, it goes long. The algo
# is a contrarian/mean reversion bet.
def handle_data(context, data):
    # Until our batch transform's datapanel is full, it will return None.  Once
    # the datapanel is full, then we have a max and min to work with.
    rval = minmax(data)
    
    if rval is None:
        return
    
    maximums, minimums = rval
    
    for stock in context.stocks:
        cur_max = maximums[stock]
        cur_min = minimums[stock]
        cur_price = data[stock].price
        cur_position = context.portfolio.positions[stock]
           
        order_direction = calculate_direction(stock, cur_min, cur_max, cur_price, cur_position)
        order_amount = calculate_order_amount(context, stock, order_direction, cur_price)
        
        # Optional: uncomment the log line below if you're looking for more detail about what's 
        # going on.  It will log all the information that is a 'moving part' of this
        # algorithm. Note: if you're doing a full backtest it's a lot of log lines!
        logmsg = '\n{s}: max {m} min {i} price {p} position amount {l}\nordering {n} shares'
        log.info(logmsg.format(
            s=stock, 
            m=cur_max, 
            i=cur_min, 
            p=cur_price, 
            l=cur_position.amount,
            n=order_amount
        ))
        
        order(stock, order_amount)
        
# Here we do our test to see if we should buy or sell or do nothing.  This is
# the main part of the algorithm. Once we establish a position (long or short)
# we use the context.long variable to remember which we took.
def calculate_direction(stock, cur_min, cur_max, cur_price, cur_position):
    if cur_max is not None and cur_position.amount <= 0 and cur_price >= cur_max:
        return -1
    elif cur_min is not None and cur_position.amount >= 0 and cur_price <= cur_min:
        return 1
    
    return 0
   
# This method is purely for order management. It calculates and returns an 
# order amount to place binary bets.
# If signal_val is -1, get to a short position of -1 * context.bet_size
# If signal_val is 1, get to a long position of context.bet_size
def calculate_order_amount(context, stock, signal_val, cur_price):
    current_amount = context.portfolio.positions[stock].amount
    abs_order_amount = int(context.bet_amount / cur_price) 
    
    if signal_val == -1:
        return (-1 * abs_order_amount) - current_amount
    elif signal_val == 1:
        return abs_order_amount - current_amount
    else:
        return 0        
            
# This is our batch transform decorator/declaration. We set the 
# refresh_period and length of the window.  In this case, once per day we're loading 
# the last 10 trading days and evaluating them.
@batch_transform(refresh_period=1, window_length=10)
def minmax(datapanel):
    # We are looking for the min and the max price to return. Just because it's interesting
    # we also are logging the current price. 
    prices_df = datapanel['price']
    min_price = prices_df.min()
    max_price = prices_df.max()

    if min_price is not None and max_price is not None:
        return (max_price, min_price)
    else:
        return None

History

# Standard Deviation Using History
# Use history() to calculate the standard deviation of the days' closing
# prices of the last 10 trading days, including price at the time of 
# calculation.
def initialize(context):
    # this example works on Apple's data
    context.aapl = symbol('AAPL')

def handle_data(context, data):
    # use history to pull the last 10 days of price
    price_history = history(bar_count=10, frequency='1d', field='price')
    # calculate the standard deviation using std()
    std = price_history.std()
    # record the standard deviation as a custom signal
    record(std=std[context.aapl])

Portfolio Allocation

def initialize(context):
    context.stocks = symbols('CERN', 'DLTR') 

def handle_data(context, data):
    # This will order as many shares as needed to
    # achieve the desired portfolio allocation.
    # In our case, we end up with 20% allocation for
    # one stock and 80% allocation for the other stock.
    order_target_percent(context.stocks[0], .2)
    order_target_percent(context.stocks[1], .8)

    # Plot portfolio allocations
    pv = float(context.portfolio.portfolio_value)
    portfolio_allocations = []
    for stock in context.stocks:
        pos = context.portfolio.positions[stock]
        portfolio_allocations.append(
            pos.last_sale_price * pos.amount / pv * 100
        )

    record(perc_stock_0=portfolio_allocations[0],
           perc_stock_1=portfolio_allocations[1])

TA-Lib Usage (RSI)




Custom Slippage

# Our custom slippage model
class PerStockSpreadSlippage(slippage.SlippageModel):

    # We specify the constructor so that we can pass state to this class, but this is optional.
    def __init__(self, spreads):
        # Store a dictionary of spreads, keyed by sid.
        self.spreads = spreads

    def process_order(self, trade_bar, my_order):
        spread = self.spreads[my_order.sid]
   
        # In this model, the slippage is going to be half of the spread for 
        # the particular stock
        slip_amount = spread / 2
        # Compute the price impact of the transaction. Size of price impact is 
        # proprotional to order size. 
        # A buy will increase the price, a sell will decrease it. 
        new_price = trade_bar.price + (slip_amount * my_order.direction)

        log.info('executing order ' + str(trade_bar.sid) + ' stock bar price: ' + \
                 str(trade_bar.price) + ' and trade executes at: ' + str(new_price))

        # Create the transaction using the new price we've calculated.
        return slippage.create_transaction(
            trade_bar,
            my_order,
            new_price,
            my_order.amount
        )

def initialize(context):
    # Provide the bid-ask spread for each of the securities in the universe.
    spreads = {
        sid(24): 0.05,
        sid(3766): 0.08
    }
   
    # Initialize slippage settings given the parameters of our model
    set_slippage(PerStockSpreadSlippage(spreads))


def handle_data(context, data):
    # We want to own 100 shares of each stock in our universe
    for stock in data:
            order_target(stock, 100)
            log.info('placing market order for ' + str(stock.symbol) + ' at price ' \
                     + str(data[stock].price))

Fetcher

import pandas

def rename_col(df):
    df = df.rename(columns={'New York 15:00': 'price'})
    df = df.rename(columns={'Value': 'price'})
    df = df.fillna(method='ffill')
    df = df[['price', 'sid']]
    # Correct look-ahead bias in mapping data to times   
    df = df.tshift(1, freq='b')
    log.info(' \n %s ' % df.head())
    return df
    
def initialize(context):
    # import the external data
    fetch_csv('https://www.quandl.com/api/v1/datasets/JOHNMATT/PALL.csv?trim_start=2012-01-01',
        date_column='Date',
        symbol='palladium',
        pre_func = preview,
        post_func=rename_col,
        date_format='%Y-%m-%d')

    fetch_csv('https://www.quandl.com/api/v1/datasets/BUNDESBANK/BBK01_WT5511.csv?trim_start=2012-01-01',
        date_column='Date',
        symbol='gold',
        pre_func = preview,
        post_func=rename_col,
        date_format='%Y-%m-%d')
    
    # Tiffany
    context.stock = symbol('TIF')

def preview(df):
    log.info(' \n %s ' % df.head())
    return df    

def handle_data(context, data):
    # Invest 10% of the portfolio in Tiffany stock when the price of gold is low.
    # Decrease the Tiffany position to 5% of portfolio when the price of gold is high.

    if (data['gold'].price < 1600):
       order_target_percent(context.stock, 0.10)
    if (data['gold'].price > 1750):
       order_target_percent(context.stock, 0.05)

    #record the variables   
    if 'price' in data['palladium']:
       record(palladium=data['palladium'].price, gold=data['gold'].price)

Record Variables




Set Universe




Basic Algorithm




Multiple Security Example




基本面選股分析 Fundamental Data Algorithm




Sample Algorithm for a Basic Strategy

Sample Algorithm for Live Trading 2