第二章量子化取引の基礎(1)

6375 ワード

2.1基礎文法とデータ構造
  • 不要変数Python推奨''宣言:
  • price_array = ['30.14', '29.58', '26.36', '32.56', '32.82']
    
    date_base = 20170118
    date_array = [str(date_base + ind) for ind, _ in enumerate(price_array)]
    

    date_array = ['20170118', '20170119', '20170120', '20170121', '20170122']
  • 名前付きメタグループ:namedtuple
  • from collections import namedtuple
    
    stock_namedtuple = namedtuple('stock', ('date', 'price'))
    stock_namedtuple_list = [stock_namedtuple(date, price) for date, price in
                             zip(date_array, price_array)]
    # namedtuple    price
    print('20170119    :{}'.format(stock_namedtuple_list[1].price))
    print(stock_namedtuple_list)
    

    20170119日の価格:29.58[stock(date='20170118',price='30.14'),stock(date='20170119',price='29.58'),...]
  • 辞書導出式
  • #      :{key: value for in}
    stock_dict = {date: price for date, price in zip(date_array, price_array)}
    print('20170119    :{}'.format(stock_dict['20170119']))
    print(stock_dict)
    

    20170119日の価格:29.58{'20170118':'30.14','20170119':'29.58',...}*辞書の格納は無秩序です
  • 秩序辞書:Orderdict
  • from collections import OrderedDict
    stock_dict = OrderedDict((date, price) for date, price in zip(date_array, price_array))
    print(stock_dict.keys())
    

    odict_keys(['20170118', '20170119', '20170120', '20170121', '20170122'])
    2.2関数
    1.組み込み関数
    需要3:前の組み合わせの辞書データから最小の終値を見つけます.
    min_price = min(zip(stock_dict.values(), stock_dict.keys()))
    

    min_price = ('26.36', '20170120')
    2.カスタム関数
    需要4:すべての終値で2番目に大きい価格要素を計算します.
    def find_second_max(dict_array):
        #      dict sorted   
        stock_price_sorted = sorted(zip(dict_array.values(), dict_array.keys()))
        #                
        return stock_price_sorted[-2]
    
    #      callable()           (call)   
    if callable(find_second_max):
        print(find_second_max(stock_dict))
    

    結果:('32.56','20170121')
    3.lambda関数
    上のlambda匿名関数を使用して、より簡潔に定義します.
    find_second_max_lambda = lambda dict_array: \
        sorted(zip(dict_array.values(), dict_array.keys()))[-2]
    print(find_second_max_lambda(stock_dict))  
    

    結果:('32.56','20170121')
  • 以上のコードlambda関数は変数を与えています.このように操作できるのはPythonのすべてがオブジェクトであるため、関数もオブジェクトです.この特徴は、開発者が他の言語で複雑な操作を完了するのに役立ちます.
  • Pythonの関数は、複数の戻り値を返すことができますが、実際には戻り値です.ただし、戻り値はtupleキューにパッケージ化することで、複数の戻り値を実現します.

  • 4.高次関数
  • map():2つのパラメータ、1つは関数で、1つはシーケンスで、map()は入力した関数をシーケンスの各要素に順次作用させ、結果を新しいシーケンスとして返す.
  • filter():2つのパラメータを受信し、1つは関数であり、1つはシーケンスであり、filter()は入力された関数を各要素に順次作用させ、戻り値がTrueであるかFalseであるかによって要素を保持するか廃棄するかを決定し、結果としてシーケンスはすべての戻り値がTrueのサブセットである.
  • reduce():1つの関数を1つのシーケンスに適用します.この関数は2つのパラメータを受信する必要があります.reduce()関数は結果をシーケンスの次の要素と累積計算し続け、reduce()関数は値結果の非シーケンスのみを返します.需要5:終値から、毎日の上昇と下落幅を導き出す.
  • pp_array = [(price1, price2) for price1, price2 in
                zip(price_float_array[:-1], price_float_array[1:])]
    

    結果:[(30.14,29.58),(29.58,26.36),(26.36,32.56),(32.56,32.82)]
    次に,高次関数map()とreduce()を用いてlambda関数と組み合わせて需要を完了し,l士iの毎日の上昇と下落幅を導いた.外層はmap()関数を使用してpp_に対してarrayの各要素は操作を実行し,内層はreduce()関数,すなわち2つの隣接する価格を用いて上昇と下落幅を求め,外層結果listに戻る.
    from functools import reduce
    # round   float       ,    3 
    change_array = list(map(lambda pp: reduce(lambda a, b: round((b-a)/a, 3), pp), pp_array))
    # list insert     ,           0
    change_array.insert(0, 0)
    print(change_array)
    

    上昇下落幅データ:[0,-0.019,-0.109,0.235,0.008]
    算出された下げ幅の上昇データをOrderedDictに追加し、namedtupleを使用してデータ構造stockを再構築します.dict
    #    namedtuple         
    stock_namedtuple = namedtuple('stock', ('date', 'price', 'change'))
    #    zip     date_array, price_array, change_array      
    # stock_namedtuple     date    key    OrderedDict
    stock_dict = OrderedDict((date, stock_namedtuple(date, price, change))
                             for date, price, change in
                             zip(date_array, price_array, change_array))
    print(stock_dict)
    

    結果:OrderedDict(('20170118',stock(date='20170118',price='30.14',change=0))),('20170119',stock(date='20170119',price='29.58',change=-0.019),...)
  • は、すべての需要を完了する汎用関数を定義します.上昇/下落をフィルタし、すべての上昇/下落の上昇/下落幅と数値を計算します.
  • def filter_stock(stock_array_dict, want_up=True, want_calc_sum=False):
        if not isinstance(stock_array_dict, OrderedDict):
            raise TypeError('stock_array_dict must be OrderedDict!')
    
        # python           
        filter_func = (lambda day: day.change > 0) \
            if want_up else (lambda day: day.change < 0)
        want_days = list(filter(filter_func, stock_array_dict.values()))
        if not want_calc_sum:
            return want_days
    
        #       
        change_sum = 0.0
        for day in want_days:
            change_sum += day.change
        return change_sum
    
    print('        :{}'.format(filter_stock(stock_dict)))
    print('        :{}'.format(filter_stock(stock_dict, want_up=False)))
    print('           :{}'.format(filter_stock(stock_dict, want_calc_sum=True)))
    print('           :{}'.format(filter_stock(stock_dict, want_up=False, want_calc_sum=True)))
    
  • すべての上昇取引日:[stock(date='20170121',price='32.56',change=0.235),stock(date='20170122',price='32.82',change=0.008)]
  • すべての下落取引日:[stock(date='20170119',price='29.58',change=-0.019),stock(date='20170120',price='26.36',change=-0.109)]
  • すべての上昇取引日の上昇幅と:0.243
  • すべての下落取引日の下落幅と:-0.128
  • 5.バイアス関数
    前の例のfilter_stock()はパラメータが多すぎるため、使いやすいときにエラーが発生します.functoolsを使用する.partial()は、呼び出し時により簡単になり、関数機能もより明確になる新しい関数を作成できます.
    from functools import partial
    
    #        
    filter_stock_up_days = partial(filter_stock, want_up=True, want_calc_sum=False)
    print('        :{}'.format(filter_stock_up_days(stock_dict)))
    
  • すべての上昇取引日:[stock(date='20170121',price='32.56',change=0.235),stock(date='20170122',price='32.82',change=0.008)]